- 实现无标题栏窗口的拖拽移动、调节窗口大小以及边框阴影效果。
- 初始化时进行位或操作,将这些标志合并为一个值,并将其设置为窗口的标志。这些标志分别表示这是一个对话框、无边框窗口、有标题栏、有最小化按钮和最大化按钮。
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_Winif (!_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;
#elsereturn QDialog::nativeEvent(eventType, message, result);
#endif
}
- 阴影效果可以使用软件的方式绘制,也可以使用图片的方式,在
paintEvent
函数实现,相对复杂,不在此描述,可看源码。 - 知识理应共享,源码在此。
- 这个demo也是学习的,使用了很多比较专的宏与函数,加的注释尽量写了用途,不清楚的自己去查吧。