Qt自定义标题栏并实现拖拽
来源:互联网 发布:笛卡尔积 sql 编辑:程序博客网 时间:2024/06/07 17:49
Qt自定义标题栏并实现拖拽
很多时候,Qt自带的窗体边框不能满足我们的需求,或者我们觉得由于系统的主题影响导致界面太丑了,我们需要自行定义一个好看并和普通标题栏功能相同的控件去替代,以达到美化我们的程序界面的目的;本文简单的实现了该功能。
下面是运行截图,由于图片选的比较丑,所以看起来不好看:
实现了鼠标拖拽事件,没有为标题栏添加鼠标右键事件以及其他美化功能,可以自行添加。
拖拽实现详解:
首先需要了解Qt的一些函数的意义:
MouseEvent中的globalPos()函数返回的是相对屏幕的位置坐标,而pos()则是返回鼠标在当前控件(即捕获该鼠标事件的控件)中的位置;
QWidget窗体的geometry().topLeft()则返回的是当前窗体的左上角在屏幕中的位置;
其次让我们看图说话,理解下窗体移动:
然后我们每次只要把上次的位置作为起始位置,就是一次次的拖拽了。
最后,我们列出算式:
startPos = event->globalPos(); // 鼠标的全局初始位置,按下时记住
curWindowPos = geometry().topleft(); // 窗体的全局位置,移动时
endPos = event->globalPos(); // 鼠标按下发生移动之后的位置,移动时
move(curWindowPos+(startPos-endPos)); // 根据矢量移动方向是初始位置减去末位置,移动时
startPos = endPos; // 将初始位置记为上次末位置,然后执行直到释放拖拽,移动时
头文件
// WindowHeader.h#ifndef WINDOWHEADER_H#define WINDOWHEADER_H#include <QLabel>#include <QWidget>#include <QToolButton>#include <QHBoxLayout>#include <QPoint>#include <QString>// 自定义控件,可拖拽标题栏class WindowHeader : public QWidget{ Q_OBJECTpublic: // 构造函数 WindowHeader(const char* appName, QWidget *parent); // 设置关闭按钮icon void SetCloseImage(const char* path); // 设置最小化按钮icon void SetMinImage(const char* path); // 设置最大化按钮icon void SetMaxImage(const char* path); // 设置迷你模式按钮icon void SetMiniImage(const char* path); // 设置软件配置按钮icon void SetSettingImage(const char* path); // 设置皮肤按钮icon void SetSkinImage(const char* path); // 设置软件LOGO按钮icon void SetAppLogo(const char* path,int w=20,int h=20); // 获取软件名 QString GetAppName() { return msAppName; }protected: // 重写鼠标事件 void mouseMoveEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); // 将信号中转,不直接处理信号signals: void ClickedClose(); void ClickedMin(); void ClickedMax(); void ClickedMini(); void ClickedSetting(); void ClickedSkin();private: // 应用名 QString msAppName; // 关闭按钮 QToolButton* mTlbtnClose; // 最小化按钮 QToolButton* mTlbtnMin; // 最大化按钮 QToolButton* mTlbtnMax; // 迷你模式按钮 QToolButton* mTlbtnMini; // 软件配置按钮 QToolButton* mTlbtnSetting; // 皮肤设置按钮 QToolButton* mTlbtnSkin; // 呈现应用名称 QLabel* mLblAppName; // 呈现应用LOGO QLabel* mLblAppLogo; // 整体布局 QHBoxLayout* mLytMain; // 鼠标上次移动开始时相对屏幕的位置 QPoint mPntStart; // 鼠标是否持续按下 bool mbKeepPressed; // 父窗口的指针 QWidget *mWidParent;};#endif // WINDOWHEADER_H
源文件
// WindowHeader.cpp#include "WindowHeader.h"#include <QMouseEvent>#include <QPixmap>#include <QIcon>WindowHeader::WindowHeader(const char* appName,QWidget *parent) :QWidget(parent),msAppName(appName){ // 父窗口指针赋值,并设置父窗口为无边框模式 mWidParent = parent; mWidParent->setWindowFlags(Qt::FramelessWindowHint | mWidParent->windowFlags()); // 初始化按钮 mTlbtnClose = new QToolButton(this); mTlbtnMin = new QToolButton(this); mTlbtnMax = new QToolButton(this); mTlbtnMini = new QToolButton(this); mTlbtnSetting = new QToolButton(this); mTlbtnSkin = new QToolButton(this); // 初始化标签 mLblAppName = new QLabel(this); mLblAppName->setText(msAppName); mLblAppLogo = new QLabel(this); // 初始化布局 mLytMain = new QHBoxLayout(this); mLytMain->setContentsMargins(2,2,2,2); mLytMain->setSpacing(2); // 设置布局 mLytMain->addWidget(mLblAppLogo); mLytMain->addWidget(mLblAppName); // 设置“弹簧”,将呈现和按钮功能分开 mLytMain->addStretch(); mLytMain->addWidget(mTlbtnSkin); mLytMain->addWidget(mTlbtnSetting); mLytMain->addWidget(mTlbtnMini); mLytMain->addWidget(mTlbtnMin); mLytMain->addWidget(mTlbtnMax); mLytMain->addWidget(mTlbtnClose); // 将内部按钮信号全部发送出去,内部不做业务逻辑绑定 connect(mTlbtnClose,SIGNAL(clicked(bool)),SIGNAL(ClickedClose())); connect(mTlbtnMax,SIGNAL(clicked(bool)),SIGNAL(ClickedMax())); connect(mTlbtnMin,SIGNAL(clicked(bool)),SIGNAL(ClickedMin())); connect(mTlbtnMini,SIGNAL(clicked(bool)),SIGNAL(ClickedMini())); connect(mTlbtnSetting,SIGNAL(clicked(bool)),SIGNAL(ClickedSetting())); connect(mTlbtnSkin,SIGNAL(clicked(bool)),SIGNAL(ClickedSkin()));}// 设置应用LOGOvoid WindowHeader::SetAppLogo(const char *path,int w,int h){ QPixmap newPix = QPixmap(path).scaled(w,h,Qt::KeepAspectRatio); mLblAppLogo->setPixmap(newPix);}void WindowHeader::SetSkinImage(const char *path){ QIcon icon(path); mTlbtnSkin->setIcon(icon);}void WindowHeader::SetSettingImage(const char *path){ QIcon icon(path); mTlbtnSetting->setIcon(icon);}void WindowHeader::SetMiniImage(const char *path){ QIcon icon(path); mTlbtnMini->setIcon(icon);}void WindowHeader::SetMaxImage(const char *path){ QIcon icon(path); mTlbtnMax->setIcon(icon);}void WindowHeader::SetMinImage(const char *path){ QIcon icon(path); mTlbtnMin->setIcon(icon);}void WindowHeader::SetCloseImage(const char *path){ QIcon icon(path); mTlbtnClose->setIcon(icon);}// 重写mouseMoveEventvoid WindowHeader::mouseMoveEvent(QMouseEvent *event){ // 持续按住才做对应事件 if (mbKeepPressed) { // 将父窗体移动到父窗体之前的位置加上鼠标移动的位置【event->globalPos()- mPntStart】 mWidParent->move(mWidParent->geometry().topLeft() + event->globalPos()- mPntStart); // 将鼠标在屏幕中的位置替换为新的位置 mPntStart = event->globalPos(); }}// 重写mousePressEventvoid WindowHeader::mousePressEvent(QMouseEvent *event){ // 鼠标左键按下事件 if (event->button() == Qt::LeftButton) { // 记录鼠标状态 mbKeepPressed = true; // 记录鼠标在屏幕中的位置 mPntStart = event->globalPos(); }}// 重写mouseReleaseEventvoid WindowHeader::mouseReleaseEvent(QMouseEvent *event){ // 鼠标左键释放 if (event->button() == Qt::LeftButton) { // 记录鼠标状态 mbKeepPressed = false; }}
原文出处:http://blog.csdn.net/motou263514/article/details/78090483
- Qt自定义标题栏并实现拖拽
- 【Qt】自定义标题栏并实现鼠标拖拽移动
- ...Qt实现--自定义标题栏
- 【Qt】自定义标题栏并实现最小化/最大化/关闭窗口功能
- Qt 个性化标题栏,自定义标题栏
- 自定义 Qt 窗口标题栏
- QT 自定义标题栏
- qt 自定义标题栏
- Qt 自定义标题栏
- Qt:自定义标题栏(QMainWindow)
- qt创建自定义标题栏
- QT自定义窗口标题栏实现拖动双击放大缩小
- Qt 之 自定义窗口标题栏
- android实现自定义标题栏
- 自定义 ToolBar 实现标题栏
- Qt自定义外观--自定义标题栏的窗口
- Qt自定义外观--自定义标题栏的窗口
- 【Qt】Qt之自定义界面(添加自定义标题栏)【转】
- CentOS7下Tomcat启动慢的原因及解决方案
- 1018. 锤子剪刀布 (20)
- python之列表
- Japan 逆序数
- 小程序页面间的跳转
- Qt自定义标题栏并实现拖拽
- 2017.09.25工作日记
- ConcurrentLinkedQueue的实现原理分析
- 顺序表
- HDU 5517 2015沈阳现场赛(二维树状数组)
- Codeforces Round #436 (Div. 2) C. Bus(模拟)
- 关于同步和异步,阻塞和非阻塞,BIO和NIO知识点
- 协议
- Codefest 17 C. Helga Hufflepuff's Cup(树形DP)