实现无标题栏窗口的拖拽移动、调节窗口大小以及边框阴影效果。 初始化时进行位或操作,将这些标志合并为一个值,并将其设置为窗口的标志。这些标志分别表示这是一个对话框、无边框窗口、有标题栏、有最小化按钮和最大化按钮。
setWindowFlags ( Qt:: Dialog | Qt:: FramelessWindowHint | Qt:: WindowTitleHint | Qt:: WindowMinimizeButtonHint | Qt:: WindowMaximizeButtonHint) ;
setAttribute ( Qt:: WA_TranslucentBackground) ;
void FramelessWindow :: paintEvent ( QPaintEvent * event)
{
QDialog :: paintEvent ( event) ;
if ( ! _shadeEnabled)
{
return ;
}
QPainterPath path;
path. setFillRule ( Qt:: WindingFill) ;
QPainter painter ( this ) ;
painter. setRenderHint ( QPainter:: Antialiasing, true ) ;
if ( this -> isMaximized ( ) || this -> isFullScreen ( ) )
{
QLayout * layout = this -> layout ( ) ;
if ( layout != NULL )
layout-> setContentsMargins ( 0 , 0 , 0 , 0 ) ;
path. addRect ( this -> rect ( ) ) ;
painter. fillPath ( path, QBrush ( Qt:: white) ) ;
return ;
}
else
{
QLayout * layout = this -> layout ( ) ;
if ( layout != NULL )
layout-> setContentsMargins ( BoardShadeWidth, BoardShadeWidth, BoardShadeWidth, BoardShadeWidth) ;
path. addRect ( BoardShadeWidth, BoardShadeWidth,
this -> width ( ) - BoardShadeWidth * 2 ,
this -> height ( ) - BoardShadeWidth * 2 ) ;
painter. fillPath ( path, QBrush ( Qt:: white) ) ;
}
painter. drawPath ( path) ;
}
定义Platform_Win ,此类仅支持windows系统,可以移动和改变大小;无法跨平台,效率高 ; 非定义Platform_Win ,支持跨平台,但是仅能实现移动,无法改变大小,效率低 ;
定义Platform_Win 方式需要重写nativeEvent
函数
bool FramelessWindow :: nativeEvent ( const QByteArray & eventType, void * message, long * result)
{
# ifdef Platform_Win
if ( ! _resizeEnabled)
{
return QDialog :: nativeEvent ( eventType, message, result) ;
}
Q_UNUSED ( eventType) ;
MSG * msg = reinterpret_cast < MSG * > ( message) ;
switch ( msg-> message)
{
case WM_NCHITTEST:
int xPos = GET_X_LPARAM ( msg-> lParam) - this -> frameGeometry ( ) . x ( ) ;
int yPos = GET_Y_LPARAM ( msg-> lParam) - this -> frameGeometry ( ) . y ( ) ;
if ( this -> childAt ( xPos, yPos) != NULL )
{
return false ;
}
QRect rect = this -> rect ( ) ;
rect. setHeight ( _doubleClickHeight) ;
if ( rect. contains ( QPoint ( xPos, yPos) ) )
{
* result = HTCAPTION;
}
if ( xPos > BoardStartPix && xPos < BoardEndPix)
* result = HTLEFT;
if ( xPos > ( this -> width ( ) - BoardEndPix) && xPos < ( this -> width ( ) - BoardStartPix) )
* result = HTRIGHT;
if ( yPos > BoardStartPix && yPos < BoardEndPix)
* result = HTTOP;
if ( yPos > ( this -> height ( ) - BoardEndPix) && yPos < ( this -> height ( ) - BoardStartPix) )
* result = HTBOTTOM;
if ( xPos > BoardStartPix && xPos < BoardEndPix && yPos > BoardStartPix && yPos < BoardEndPix)
* result = HTTOPLEFT;
if ( xPos > ( this -> width ( ) - BoardEndPix) && xPos < ( this -> width ( ) - BoardStartPix) && yPos > BoardStartPix && yPos < BoardEndPix)
* result = HTTOPRIGHT;
if ( xPos > BoardStartPix && xPos < BoardEndPix && yPos > ( this -> height ( ) - BoardEndPix) && yPos < ( this -> height ( ) - BoardStartPix) )
* result = HTBOTTOMLEFT;
if ( xPos > ( this -> width ( ) - BoardEndPix) && xPos < ( this -> width ( ) - BoardStartPix) && yPos > ( this -> height ( ) - BoardEndPix) && yPos < ( this -> height ( ) - BoardStartPix) )
* result = HTBOTTOMRIGHT;
return true ;
}
return false ;
# else
return QDialog :: nativeEvent ( eventType, message, result) ;
# endif
}
阴影效果可以使用软件的方式绘制,也可以使用图片的方式,在paintEvent
函数实现 ,相对复杂,不在此描述,可看源码。知识理应共享,源码在此。 这个demo也是学习的,使用了很多比较专的宏与函数,加的注释尽量写了用途,不清楚的自己去查吧。