01QT编写自己的UC浏览器-编写带标题栏和Aero效果的浏览器框架

xiaoxiao2021-02-28  142

1.编写windows下带Aero特效的QT窗口

简介:主要设计QT无边框窗口,如果单纯使用QT常用功能可以设计出支持缩放,拖拽,阴影等功能,但是windows自带的非常实用的snap效果确很难做到尽善尽美。因此这里使用的是QT5之后支持的功能,来设计带WINDOWS下的阴影、缩放、拖拽、Aero Snap效果的窗口。

参考博客:http://www.cnblogs.com/findumars/p/6204345.html

参考代码:https://github.com/deimos1877/BorderlessWindow

少走弯路:

1).之前设计的出支持缩放,拖拽,阴影等功能的QT窗口,缩放使用的是NativeEvent()函数,拖拽使用的是根据鼠标按住和松开位置进行move(x,y),阴影使用的是paintEvent()函数。设计效果如下:

参考代码:http://download.csdn.net/detail/qq_31215157/9922187

2).http://blog.csdn.net/imxiangzi/article/details/49962365 和 http://blog.csdn.net/jan5_reyn/article/details/39042197 这两篇博客介绍的仅仅是毛玻璃特效,在无边框的QT窗口无法满足一些功能,如边界自动缩放尺寸等,不建议参考。

设计说明:

参考代码解析:

1)按键控制:F6边框控制,F7阴影控制,F5未知

case WM_KEYDOWN: { switch ( wParam ) { case VK_F5: { window->borderlessResizeable = !window->borderlessResizeable; break; } case VK_F6: { window->toggleShadow(); window->toggleBorderless(); SetFocus( winId ); break; } case VK_F7: { window->toggleShadow(); break; } } if ( wParam != VK_TAB ) return DefWindowProc( hWnd, message, wParam, lParam ); SetFocus( winId ); break; }2)控制拖拽,拖拽宽度可调,默认为5,不影响最大化显示。 case WM_NCHITTEST: { if ( window->borderless ) { if ( window->borderlessResizeable ) { const LONG borderWidth = 5; //in pixels RECT winrect; GetWindowRect( hWnd, &winrect ); long x = GET_X_LPARAM( lParam ); long y = GET_Y_LPARAM( lParam ); //bottom left corner if ( x >= winrect.left && x < winrect.left + borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth ) { return HTBOTTOMLEFT; } //bottom right corner if ( x < winrect.right && x >= winrect.right - borderWidth && y < winrect.bottom && y >= winrect.bottom - borderWidth ) { return HTBOTTOMRIGHT; } //top left corner if ( x >= winrect.left && x < winrect.left + borderWidth && y >= winrect.top && y < winrect.top + borderWidth ) { return HTTOPLEFT; } //top right corner if ( x < winrect.right && x >= winrect.right - borderWidth && y >= winrect.top && y < winrect.top + borderWidth ) { return HTTOPRIGHT; } //left border if ( x >= winrect.left && x < winrect.left + borderWidth ) { return HTLEFT; } //right border if ( x < winrect.right && x >= winrect.right - borderWidth ) { return HTRIGHT; } //bottom border if ( y < winrect.bottom && y >= winrect.bottom - borderWidth ) { return HTBOTTOM; } //top border if ( y >= winrect.top && y < winrect.top + borderWidth ) { return HTTOP; } } return HTCAPTION; } break; } 3)标题栏中的最大化按钮回调,并改变按钮图标。用于控制窗口最大化和正常化。

case WM_SIZE: { RECT winrect; GetClientRect( hWnd, &winrect ); WINDOWPLACEMENT wp; wp.length = sizeof( WINDOWPLACEMENT ); GetWindowPlacement( hWnd, &wp ); if ( wp.showCmd == SW_MAXIMIZE ) { QPushButton* pushButtonMaximize = mainPanel->findChild<QPushButton*>( "pushButtonMaximize" ); pushButtonMaximize->setStyleSheet( "#pushButtonMaximize {image: url(:/SystemMenu/Icons/Restore.png);} #pushButtonMaximize:hover { image: url(:/SystemMenu/Icons/RestoreHover.png); }" ); mainPanel->setGeometry( MARGIN, MARGIN, winrect.right-MARGIN*2, winrect.bottom-MARGIN*2 ); } else { QPushButton* pushButtonMaximize = mainPanel->findChild<QPushButton*>( "pushButtonMaximize" ); pushButtonMaximize->setStyleSheet( "#pushButtonMaximize {image: url(:/SystemMenu/Icons/Maximize.png);} #pushButtonMaximize:hover { image: url(:/SystemMenu/Icons/MaximizeHover.png); }" ); mainPanel->setGeometry( 0, 0, winrect.right , winrect.bottom ); } return DefWindowProc(hWnd, message, wParam, lParam); }注意:MARGIN用于控制最大化的显示坐标偏差问题。

4)无边框效果处理函数,调用了windows默认的接口。

void BorderlessWindow::toggleBorderless() { if ( visible ) { Style newStyle = ( borderless ) ? Style::windowed : Style::aero_borderless; SetWindowLongPtr( hWnd, GWL_STYLE, static_cast<LONG>( newStyle ) ); borderless = !borderless; if ( newStyle == Style::aero_borderless ) { toggleShadow(); } //redraw frame SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE ); show(); } }注意:参考代码会出现刚打开有边框然后立刻跳成无边框问题,可以将初始化中

borderlessResizeable( false ),改成 borderlessResizeable( true ) //先执行无边框,在执行显示函数。 toggleBorderless(); show(); 5)之前尝试吧QWinWidget类替换成Qmainwindows,增加其通用性,但是无法实现。因此建议就使用QWinWidget类作为主窗口类,添加的其他UI控件可以正常布局添加即可。

2.添加QTabWidget用于web的widget.并显示一组网页。

此处的TabWidget类参考的QT自带源码Simplebrowser。

m_tabWidget = new TabWidget(); m_tabWidget->createTab(); m_tabWidget->setUrl(QUrl::fromUserInput("http://www.qt.io")); m_tabWidget->createTab(); m_tabWidget->setUrl(QUrl::fromUserInput("http://www.baidu.com"));3.为QT添加程序图标

1)法1:添加图标文件到资源,在main函数的起始添加代码:

app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg")));此法用于QWidget QApplication等相关的QT原生类进行图标设置。 2)法2:添加图标文件和rc文件到资源,rc文件代码:

IDI_ICON1 ICON DISCARDABLE "skin/images/QFramer.ico"

此法用于QWidget QApplication等相关的QT原生类进行图标设置。

3)直接在.pro文件最后添加

RC_ICONS = logo.ico

此法用于Release生成的exe文件添加图标。

4)为WINAPI应用添加图标

设置窗口参数中的HICON参数,可以使用载入图片的方式:

LPCWSTR iconName = TEXT("logo.ico"); wcx.hIcon = (HICON)LoadImage( NULL, //handle of the instance that contains //the image iconName,//name or identifier of image IMAGE_ICON,//type of image-can also be IMAGE_CURSOR or MAGE_ICON 0,0,//desired width and height LR_LOADFROMFILE);//load flags 注意QT文件名默认为char*类型,上述定义了LPCWSTR类型的文件名,避免了格式错误。

上述3)4)两种方式结合用于WINAPI的窗口类进行窗口图标和exe文件图标添加。 本章程序截图:

图标显示:

程序源码下载地址:

转载请注明原文地址: https://www.6miu.com/read-26759.html

最新回复(0)