- 实现无标题栏窗口的拖拽移动、调节窗口大小以及边框阴影效果。
- 初始化时进行位或操作,将这些标志合并为一个值,并将其设置为窗口的标志。这些标志分别表示这是一个对话框、无边框窗口、有标题栏、有最小化按钮和最大化按钮。
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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 定义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
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 阴影效果可以使用软件的方式绘制,也可以使用图片的方式,在
paintEvent
函数实现,相对复杂,不在此描述,可看源码。 - 知识理应共享,源码在此。
- 这个demo也是学习的,使用了很多比较专的宏与函数,加的注释尽量写了用途,不清楚的自己去查吧。