赞
踩
大家在用QT进行客户端开发的时候,难免都会觉得原生的QT窗口标题栏很丑,希望能自绘漂亮的标题栏,实现方法其实也比较简单,网上资料也挺多,方法基本都差不多,不过我觉得不够简洁,对此我特地封装总结了一个最高效快捷的方法,3分钟实现一个自绘制标题栏,包含:左上角图标、标题、按钮、双击标题栏、最大化时候拖拽缩小、菜单栏等功能。
1、目标窗口添加标题栏、最大化最小化关闭按钮(该步最好每次使用时,从模板程序中直接复制)
2、窗口基类从QDialog改为QFramelessDialog,如果是QWidget的话,请参考QFramelessDialog自行编写QFramelessWidget即可,非常简单,只需要将QDialog改成QWidget即可,至于为什么我写程序更喜欢用QDialog而不是QWidget,主要原因是QDialog默认自带外边框,设置外边框更简单,而QWidget设置外边框比较麻烦,必须在ui中将边框宽度pad预留出来。
3、窗口构造函数中,调用无边框窗体初始化函数,头文件中已经写好几个宏函数直接调用即可,使用宏的情况下,必须保证标题栏、按钮对象名称一致,注意调用初始化函数一定要在ui.setupUi(this);后面。
核心初始化函数
- void Init(QWidget *widget_title, //标题栏对象
- QPushButton *menuButton_Close,//关闭按钮
- QPushButton *menuButton_Max, //最大化按钮
- QPushButton *menuButton_Min, //最小化按钮
- bool bResize, //窗体支持resize
- bool bMinHide, //点击close按钮时隐藏窗口,通常用在主窗口中
- bool bConnectClose); //当bMinHide为true时,是否自动处理隐藏
宏解释:
FRAMELESS_DIALOG_INIT 模态对话框(只有关闭按钮)
FRAMELESS_MAIN_DIALOG_INIT 常用主窗口(包含最大化 、最小化、关闭按钮、可resize)
关于Demo中qss样式、编辑可参考作者早期博文《QT-智能QSS设计器》
https://blog.csdn.net/redchairman/article/details/82012984
- #ifndef QFRAMELESSDIALOG_H
- #define QFRAMELESSDIALOG_H
-
- #include <QDialog>
-
- class QFramelessDialog : public QDialog
- {
- Q_OBJECT
-
- public:
- QFramelessDialog(QWidget *parent);
- ~QFramelessDialog();
-
- void Init(QWidget *widget_title,
- QPushButton *menuButton_Close,
- QPushButton *menuButton_Max,
- QPushButton *menuButton_Min,
- bool bResize,
- bool bMinClose,
- bool bConnectClose);
-
- void setResizeable(bool resizeable);
- virtual void CloseDialog();
- private:
- bool m_bMaximized;
- bool m_bMoveable;
- QPoint dragPosition;
- QRect m_rcNormal;
-
- protected:
- void mouseMoveEvent(QMouseEvent *e);
- void mousePressEvent(QMouseEvent *e);
- void mouseReleaseEvent(QMouseEvent *);
- void mouseDoubleClickEvent(QMouseEvent *event);
-
- bool nativeEvent(const QByteArray & eventType, void * message, long * result);
-
- void paintEvent(QPaintEvent *event);
-
- void keyPressEvent(QKeyEvent* e);
-
- public slots:
- /* void sltCloseClick();*/
- void sltClickMin();
- void sltClickMaxRestore();
- void sltCloseDialog();
-
- public:
- bool m_bResize;
- QPushButton *m_menuButton_Close;
- QPushButton *m_menuButton_Max;
- QPushButton *m_menuButton_Min;
- QWidget *m_widget_title;
- bool m_bMinClose;
- bool m_bConnectClose;
- };
-
- #define FRAMELESS_DIALOG_INIT() Init(ui.widget_title, ui.menuButton_Close, nullptr, nullptr, false, false, true)
- #define FRAMELESS_MAIN_DIALOG_INIT() Init(ui.widget_title, ui.menuButton_Close, ui.menuButton_Max, ui.menuButton_Min, true, true, true)
- #define FRAMELESS_MAIN_DIALOG_NOCLOSE_INIT() Init(ui.widget_title, ui.menuButton_Close, ui.menuButton_Max, ui.menuButton_Min, true, true, false)
-
- #define FRAMELESS_DIALOG_INIT2() Init(ui->widget_title, ui->menuButton_Close, nullptr, nullptr, false, false, true)
- #define FRAMELESS_MAIN_DIALOG_INIT2() Init(ui->widget_title, ui->menuButton_Close, ui->menuButton_Max, ui->menuButton_Min, true, true, true)
- #define FRAMELESS_MAIN_DIALOG_NOCLOSE_INIT2() Init(ui->widget_title, ui->menuButton_Close, ui->menuButton_Max, ui->menuButton_Min, true, true, false)
-
-
-
-
- #endif // QFRAMELESSDIALOG_H
- #include "stdafx.h"
- #include "QFramelessDialog.h"
- #include "QIconHelper.hpp"
-
- QFramelessDialog::QFramelessDialog(QWidget *parent)
- : QDialog(parent)
- , m_bMaximized(false)
- , m_bMoveable(false)
- , m_bResize(false)
- , m_menuButton_Close(nullptr)
- , m_menuButton_Max(nullptr)
- , m_menuButton_Min(nullptr)
- , m_widget_title(nullptr)
- , m_bMinClose(false)
- {
- /* setAttribute(Qt::WA_TranslucentBackground);*/
- setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowMinMaxButtonsHint);
- setWindowModality(Qt::WindowModal);
- setFocusPolicy(Qt::ClickFocus);
- }
-
- QFramelessDialog::~QFramelessDialog()
- {
-
- }
-
- void QFramelessDialog::Init(QWidget *widget_title,
- QPushButton *menuButton_Close,
- QPushButton *menuButton_Max,
- QPushButton *menuButton_Min,
- bool bResize,
- bool bMinClose,
- bool bConnectClose)
- {
- m_bResize = bResize;
- m_bMinClose = bMinClose;
- m_bConnectClose = bConnectClose;
- m_menuButton_Min = menuButton_Min;
- m_menuButton_Max = menuButton_Max;
- m_menuButton_Close = menuButton_Close;
- m_widget_title = widget_title;
-
- if (m_menuButton_Close)
- {
- m_menuButton_Close->setFocusPolicy(Qt::ClickFocus);
- QIconHelper::SetIcon(m_menuButton_Close, QChar(0xf00d), 12);
- if (m_bMinClose)
- {
- if (m_bConnectClose)
- {
- connect(m_menuButton_Close, SIGNAL(clicked()), this, SLOT(hide()));
- }
- }
- else
- {
- connect(m_menuButton_Close, SIGNAL(clicked()), this, SLOT(sltCloseDialog()));
- }
- }
- if (m_menuButton_Max)
- {
- m_menuButton_Max->setFocusPolicy(Qt::ClickFocus);
- QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf096), 12);
- connect(m_menuButton_Max, SIGNAL(clicked()), this, SLOT(sltClickMaxRestore()));
- }
- if (m_menuButton_Min)
- {
- m_menuButton_Min->setFocusPolicy(Qt::ClickFocus);
- QIconHelper::SetIcon(m_menuButton_Min, QChar(0xf068), 12);
- connect(m_menuButton_Min, SIGNAL(clicked()), this, SLOT(sltClickMin()));
- }
-
- return;
- }
-
- void QFramelessDialog::CloseDialog()
- {
- close();
- }
-
- void QFramelessDialog::sltCloseDialog()
- {
- CloseDialog();
- }
-
- void QFramelessDialog::mousePressEvent(QMouseEvent *event)
- {
- if (isFullScreen())
- {
- return;
- }
-
- if (event->button() == Qt::LeftButton && m_widget_title)
- {
- dragPosition = event->globalPos() - frameGeometry().topLeft();
-
- QRect rect = m_widget_title->rect();
- if (rect.contains(event->pos()))
- {
- m_bMoveable = true;
- }
- }
- event->accept();
- }
-
- void QFramelessDialog::mouseMoveEvent(QMouseEvent *event)
- {
- if (isFullScreen())
- {
- return;
- }
-
- if (event->buttons() & Qt::LeftButton && m_bMoveable)
- {
- if (isMaximized())
- {
- int nWidth = m_rcNormal.width();
- int nHeight = m_rcNormal.height();
-
- float fx = (float)event->pos().x() / (float)rect().width();
- //屏幕大小
- int old_x = m_rcNormal.width() * fx + m_rcNormal.left();
- int old_y = m_rcNormal.top() + event->pos().y();
-
- QPoint pt_new(m_rcNormal.left() + event->globalPos().x() - old_x, m_rcNormal.top() + event->globalPos().y() - old_y);
- m_rcNormal.moveTopLeft(pt_new);
- sltClickMaxRestore();
- //m_rcNormal
- dragPosition = event->globalPos() - frameGeometry().topLeft();
- }
- else
- {
- move(event->globalPos() - dragPosition);
- }
- }
- event->accept();
-
- }
-
- void QFramelessDialog::mouseReleaseEvent(QMouseEvent *event)
- {
- if (isFullScreen())
- {
- return;
- }
- if (m_bMoveable)
- {
- m_bMoveable = false;
- }
- event->accept();
- }
-
- void QFramelessDialog::mouseDoubleClickEvent(QMouseEvent *event)
- {
- if (m_bResize == false)
- {
- return;
- }
- if (m_menuButton_Max == nullptr || m_menuButton_Min == nullptr)
- {
- return;
- }
- if (isFullScreen())
- {
- return;
- }
- if (event->buttons() & Qt::LeftButton && m_widget_title)
- {
- QRect rect = m_widget_title->rect();
- if (rect.contains(event->pos()))
- {
- sltClickMaxRestore();
- }
- }
- event->accept();
- }
-
- void QFramelessDialog::sltClickMin()
- {
- showMinimized();
- }
-
- void QFramelessDialog::sltClickMaxRestore()
- {
- if (isMaximized())
- {
- showNormal();
- setGeometry(m_rcNormal);
- qDebug() << m_rcNormal;
-
- QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf096), 10);
- m_menuButton_Max->setToolTip(QStringLiteral("最大化"));
- }
- else
- {
- m_rcNormal = geometry();
- showMaximized();
-
- QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf079), 10);
- m_menuButton_Max->setToolTip(QStringLiteral("还原"));
- }
- }
-
- bool QFramelessDialog::nativeEvent(const QByteArray & eventType, void * message, long * result)
- {
- Q_UNUSED(eventType);
- const int HIT_BORDER = 4;
- const MSG *msg = static_cast<MSG*>(message);
-
- if (msg->message == WM_NCCALCSIZE)
- {
- *result = 0;
- return true;
- }
- else if (msg->message == WM_NCHITTEST)
- {
- if (m_bResize == false || m_widget_title == nullptr)
- {
- return QDialog::nativeEvent(eventType, message, result);
- }
-
- if (isMaximized())
- {
- return false;
- }
- int xPos = ((int)(short)LOWORD(msg->lParam)) - this->frameGeometry().x();
- int yPos = ((int)(short)HIWORD(msg->lParam)) - this->frameGeometry().y();
-
- if (xPos >= 0 && xPos < HIT_BORDER && yPos >= 0 && yPos < HIT_BORDER) {
- *result = HTTOPLEFT;
- return true;
- }
- if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos > 0 && yPos < HIT_BORDER) {
- *result = HTTOPRIGHT;
- return true;
- }
- if (xPos > 0 && xPos < HIT_BORDER && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
- *result = HTBOTTOMLEFT;
- return true;
- }
- if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
- *result = HTBOTTOMRIGHT;
- return true;
- }
- if (xPos >= 0 && xPos < HIT_BORDER) {
- *result = HTLEFT;
- return true;
- }
- if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0)) {
- *result = HTRIGHT;
- return true;
- }
- if (yPos >= 0 && yPos < HIT_BORDER) {
- *result = HTTOP;
- return true;
- }
- if (yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
- *result = HTBOTTOM;
- return true;
- }
- if (m_widget_title->geometry().contains(QPoint(xPos, yPos)))
- {
- *result = HTCAPTION;
- return false;
- }
- return false;
- }
- return false;
- }
-
- #define SHADOW_BORDER 6
- void QFramelessDialog::paintEvent(QPaintEvent *event)
- {
- return QDialog::paintEvent(event);
- //
- // QPainterPath path;
- // path.setFillRule(Qt::WindingFill);
- // path.addRect(SHADOW_BORDER, SHADOW_BORDER, this->width()-2*SHADOW_BORDER, this->height()-2*SHADOW_BORDER);
- //
- // QPainter painter(this);
- // painter.setRenderHint(QPainter::Antialiasing, true);
- // painter.fillPath(path, QBrush(Qt::white));
- //
- // QColor color(0, 0, 0, 60);
- // for(int i=0; i<SHADOW_BORDER; i++)
- // {
- // QPainterPath path;
- // path.setFillRule(Qt::WindingFill);
- // path.addRect(SHADOW_BORDER-1-i, SHADOW_BORDER-1-i, this->width()-(SHADOW_BORDER-i)*2, this->height()-(SHADOW_BORDER-i)*2);
- // color.setAlpha(40 - i * 7);
- // painter.setPen(color);
- // painter.drawPath(path);
- // }
- }
-
- void QFramelessDialog::keyPressEvent(QKeyEvent* e)
- {
- qDebug()<<e->key();
- switch (e->key())
- {
- case Qt::Key_Return:
- break;
- case Qt::Key_Enter:
- break;
- case Qt::Key_Escape:
- {
- if (m_bMinClose)
- break;
- }
- default:
- QDialog::keyPressEvent(e);
- }
- }
-
调用示例:
- #include <QDialog>
- #include "ui_QSubDialog.h"
- #include "QFramelessDialog.h"
-
- class QSubDialog : public QFramelessDialog
- {
- Q_OBJECT
-
- public:
- QSubDialog(QWidget *parent = 0);
- ~QSubDialog();
-
- private:
- Ui::QSubDialog ui;
- };
- #include "stdafx.h"
- #include "QSubDialog.h"
-
- QSubDialog::QSubDialog(QWidget *parent)
- : QFramelessDialog(parent)
- {
- ui.setupUi(this);
- FRAMELESS_DIALOG_INIT();
- }
-
- QSubDialog::~QSubDialog()
- {
-
- }
https://download.csdn.net/download/redchairman/12914480
群号码:1149411109
群名称:Qt实战派学习群
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。