范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Qt高级Qt自定义标题栏

  QWidget及其子类窗体组件的标题栏受操作系统的控制,即标题栏的界面风格与操作系统的主题风格相同,工程实践中需要开发者自行定一,达到美化应用程序界面的目的。
  一、Qt自定义标题栏实现
  1、自定义标题栏的功能
  自定义标题栏需要完成功能如下:
  (1)自定义标题栏需要包含最小化按钮、最大化按钮、关闭按钮、标题标签、图标标签等图形元素。
  (2)标题栏的拖拽。
  (3)鼠标双击标题栏实现窗体的最大化、最小化。
  2、自定义标题栏的界面布局
  自定义标题栏的界面布局如下:
  3、标题栏拖拽功能的实现
  窗体的拖拽平移过程如下图:
  当鼠标在窗体的标题栏按下并移动时,窗体会按照鼠标移动的轨迹进行平移。因此,窗体每次移动都是在当前位置按照鼠标移动的矢量进行移动。标题栏拖拽功能的实现需要实现mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件处理函数。
  MouseEvent中的globalPos()函数返回的是相对屏幕的位置坐标,而pos()则是返回鼠标在当前控件(即捕获该鼠标事件的控件)中的位置。QWidget窗体的geometry().topLeft()则返回的是当前窗体的左上角在屏幕中的位置。 startPos = event->globalPos();// 鼠标的全局初始位置,按下时记住 curWindowPos = geometry().topleft();// 窗体的全部位置,移动时 endPos = event->globalPos();// 鼠标按下发生移动之后的位置,移动时 move(curWindowPos+(startPos-endPos));// 根据矢量移动方向是初始位置减去末位置,移动时 startPos = endPos;// 将初始位置记为上次末位置,然后执行直到释放拖拽,移动时
  实现代码如下:void TitleBar::mousePressEvent(QMouseEvent *event) { // 鼠标左键按下事件 if (event->button() == Qt::LeftButton) { // 记录鼠标左键状态 m_leftButtonPressed = true; //记录鼠标在屏幕中的位置 m_start = event->globalPos(); } } void TitleBar::mouseMoveEvent(QMouseEvent *event) { // 持续按住才做对应事件 if(m_leftButtonPressed) { //将父窗体移动到父窗体原来的位置加上鼠标移动的位置:event->globalPos()-m_start parentWidget()->move(parentWidget()->geometry().topLeft() + event->globalPos() - m_start); //将鼠标在屏幕中的位置替换为新的位置 m_start = event->globalPos(); } } void TitleBar::mouseReleaseEvent(QMouseEvent *event) { // 鼠标左键释放 if (event->button() == Qt::LeftButton) { // 记录鼠标状态 m_leftButtonPressed = false; } }
  4、标题栏双击实现最大化、最小化
  鼠标双击事件处理函数mouseDoubleClickEvent实现如下:void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) { m_maximizeButton->click(); }
  最大化、最小化、关闭按钮的槽函数如下:void TitleBar::onClicked() { QPushButton *pButton = qobject_cast(sender()); QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { if (pButton == m_minimizeButton) { pWindow->showMinimized(); } else if (pButton == m_maximizeButton) { pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized(); } else if (pButton == m_closeButton) { pWindow->close(); } } }
  二、Qt自定义窗体基类示例
  1、自定义窗体基类的功能
  自定义窗体基类的功能如下:
  (1)自定义标题栏。
  (2)增加内容组件,内容组件内部的界面布局完全由具体的用户决定。
  2、自定义窗体基类的实现
  TitleBar.h文件:#ifndef TITLEBAR_H #define TITLEBAR_H #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  /** * @brief 标题栏界面组件 * @author */ class TitleBar : public QWidget { Q_OBJECT public: explicit TitleBar(QWidget *parent = NULL); /** * @brief 设置标题栏标题 * @param title,参数,设置的标题 */ void setWindowTitle(const QString& title); /** * @brief 设置标题栏的图标 * @param iconPath,参数,图标的路径 */ void SetTitleBarIcon(const QString& iconPath); protected: /** * @brief 鼠标双击事件处理函数 * @param event,参数,事件 * @note 双击标题栏进行界面的最大化/还原 */ virtual void mouseDoubleClickEvent(QMouseEvent *event); /** * @brief 鼠标按下事件处理函数 * @param event,参数,事件 * @note 按下鼠标左键 */ virtual void mousePressEvent(QMouseEvent *event); /** * @brief 鼠标移动事件处理函数 * @param event,参数,事件 * @note 移动鼠标 */ virtual void mouseMoveEvent(QMouseEvent *event); /** * @brief 鼠标释放事件处理函数 * @param event,参数,事件 * @note 释放鼠标 */ virtual void mouseReleaseEvent(QMouseEvent *event); /** * @brief 事件过滤处理器 * @param obj,参数 * @param event,参数,事件 * @return 成功返回true,失败返回false * @note 设置标题、图标 */ virtual bool eventFilter(QObject *obj, QEvent *event); /** * @brief 最大化/还原 */ void updateMaximize(); protected slots: /** * @brief 最小化、最大化/还原、关闭按钮点击时响应的槽函数 */ void onClicked(); private: QLabel* m_iconLabel; QLabel* m_titleLabel; QPushButton* m_minimizeButton; QPushButton* m_maximizeButton; QPushButton* m_closeButton; QPoint m_start;//起始点 QPoint m_end;//结束点 bool m_leftButtonPressed;//鼠标左键按下标记 }; #endif // TITLEBAR_H
  TitleBar.cpp文件:#include "TitleBar.h" TitleBar::TitleBar(QWidget *parent) : QWidget(parent) { setFixedHeight(30); setWindowFlags(Qt::FramelessWindowHint); m_iconLabel = new QLabel(this); m_iconLabel->setFixedSize(20, 20); m_iconLabel->setScaledContents(true); m_titleLabel = new QLabel(this); m_titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_minimizeButton = new QPushButton(this); m_minimizeButton->setFixedSize(27, 22); m_minimizeButton->setObjectName("minimizeButton"); m_maximizeButton = new QPushButton(this); m_maximizeButton->setFixedSize(27, 22); m_maximizeButton->setObjectName("maximizeButton"); m_closeButton = new QPushButton(this); m_closeButton->setFixedSize(27, 22); m_closeButton->setObjectName("closeButton"); QHBoxLayout* layout = new QHBoxLayout; layout->addWidget(m_iconLabel); layout->addStretch(1); layout->addWidget(m_titleLabel); layout->addStretch(1); layout->addWidget(m_minimizeButton); layout->addWidget(m_maximizeButton); layout->addWidget(m_closeButton); setLayout(layout); setProperty("titleBar", true); setObjectName("titleBar"); connect(m_minimizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(m_maximizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); } void TitleBar::setWindowTitle(const QString &title) { m_titleLabel->setAlignment(Qt::AlignCenter); m_titleLabel->setText(title); } void TitleBar::SetTitleBarIcon(const QString &iconPath) { QPixmap map(iconPath); m_iconLabel->setPixmap(map); } void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) { m_maximizeButton->click(); } void TitleBar::mousePressEvent(QMouseEvent *event) { // 鼠标左键按下事件 if (event->button() == Qt::LeftButton) { // 记录鼠标左键状态 m_leftButtonPressed = true; //记录鼠标在屏幕中的位置 m_start = event->globalPos(); } } void TitleBar::mouseMoveEvent(QMouseEvent *event) { // 持续按住才做对应事件 if(m_leftButtonPressed) { //将父窗体移动到父窗体原来的位置加上鼠标移动的位置:event->globalPos()-m_start parentWidget()->move(parentWidget()->geometry().topLeft() + event->globalPos() - m_start); //将鼠标在屏幕中的位置替换为新的位置 m_start = event->globalPos(); } } void TitleBar::mouseReleaseEvent(QMouseEvent *event) { // 鼠标左键释放 if (event->button() == Qt::LeftButton) { // 记录鼠标状态 m_leftButtonPressed = false; } } bool TitleBar::eventFilter(QObject *obj, QEvent *event) { switch(event->type()) { //设置标题 case QEvent::WindowTitleChange: { QWidget *pWidget = qobject_cast(obj); if (pWidget) { m_titleLabel->setText(pWidget->windowTitle()); return true; } } //设置图标 case QEvent::WindowIconChange: { QWidget *pWidget = qobject_cast(obj); if (pWidget) { QIcon icon = pWidget->windowIcon(); m_iconLabel->setPixmap(icon.pixmap(m_iconLabel->size())); return true; } } // 窗口状态变化、窗口大小变化 case QEvent::WindowStateChange: case QEvent::Resize: updateMaximize(); return true; } return QWidget::eventFilter(obj, event); } void TitleBar::updateMaximize() { QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { bool bMaximize = pWindow->isMaximized(); if (bMaximize) { m_maximizeButton->setToolTip(tr("Restore")); m_maximizeButton->setProperty("maximizeProperty", "restore"); } else { m_maximizeButton->setProperty("maximizeProperty", "maximize"); m_maximizeButton->setToolTip(tr("Maximize")); } m_maximizeButton->setStyle(QApplication::style()); } } void TitleBar::onClicked() { QPushButton *pButton = qobject_cast(sender()); QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { if (pButton == m_minimizeButton) { pWindow->showMinimized(); } else if (pButton == m_maximizeButton) { pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized(); } else if (pButton == m_closeButton) { pWindow->close(); } } }
  QWindowBase.h文件:#ifndef QWINDOWBASE_H #define QWINDOWBASE_H #include  #include  #include  #include "TitleBar.h" /** * @brief 界面组件基类 * @note QWindowBase界面组件主要用作顶层窗口,对于非顶层窗口的界面组件使用QWidget。 */ class QWindowBase : public QFrame { Q_OBJECT public: QWindowBase(QFrame* parent = NULL); /** * @brief 设置标题 * @param title,输入参数,标题内容 */ void setWindowTitle(const QString& title); /** * @brief 设置标题栏的图标 * @param iconPath,输入参数,图标资源路径 */ void SetTitleBarIcon(const QString& iconPath); /** * @brief 获取内容组件对象指针 * @return 返回QWidget* */ QWidget* contentWidget(); /** * @brief 设置标题栏高度 * @param h,输入参数,标题栏高度 */ void setWindowTitleHeight(int h); private: QWidget* m_contentWidget;//内容组件 TitleBar* m_titleBar;//标题栏 QVBoxLayout* m_layout;//布局管理器 }; #endif // QWINDOWBASE_H
  QWindowBase.cpp文件:#include "QWindowBase.h" QWindowBase::QWindowBase(QFrame *parent): QFrame(parent) { setWindowFlags(windowFlags() | Qt::FramelessWindowHint); m_titleBar = new TitleBar(this); m_contentWidget = new QWidget(this); m_contentWidget->setObjectName("Contents"); m_layout = new QVBoxLayout; m_layout->addWidget(m_titleBar); m_layout->addWidget(m_contentWidget); m_layout->setSpacing(0); m_layout->setContentsMargins(0, 0, 0, 0); setLayout(m_layout); } void QWindowBase::setWindowTitle(const QString &title) { m_titleBar->setWindowTitle(title); } void QWindowBase::SetTitleBarIcon(const QString &iconPath) { m_titleBar->SetTitleBarIcon(iconPath); } QWidget *QWindowBase::contentWidget() { return m_contentWidget; } void QWindowBase::setWindowTitleHeight(int h) { m_titleBar->setFixedHeight(h); }
  CommonHelper.h文件:#ifndef COMMONHELPER_H #define COMMONHELPER_H #include  #include  #include  #include  #include  #include  /** * @brief 通用功能辅助类 */ class CommonHelper { public: /** * @brief 为应用程序设置QSS样式表 * @param filepath,输入参数,QSS文件路径 */ static void setStyleSheet(const QString& filepath) { //加载样式文件 QFile qss(filepath); if(qss.open(QFile::ReadOnly)) { QString stylesheet = QLatin1String(qss.readAll()); QString paletteColor = stylesheet.mid(20, 7); qApp->setPalette(QPalette(QColor(paletteColor))); qApp->setStyleSheet(stylesheet); } } }; #endif // COMMONHELPER_H
  点击领取Qt学习资料+视频教程~「链接」
  main.cpp文件:#include  #include "CommonHelper.h" #include "QWindowBase.h" #include  #include  #include  #include  int main(int argc, char *argv[]) { QApplication a(argc, argv); QWindowBase w; w.setWindowTitle("WidgetBase"); QPushButton* button1 = new QPushButton("OK"); QHBoxLayout* hLayout1 = new QHBoxLayout; hLayout1->addStretch(1); hLayout1->addWidget(button1); QVBoxLayout* layout = new QVBoxLayout; QTreeView* treeView = new QTreeView; layout->addWidget(treeView); layout->addLayout(hLayout1); layout->addStretch(1); w.contentWidget()->setLayout(layout); w.setWindowTitleHeight(40); w.show(); CommonHelper::setStyleSheet("://qss/lightblue.qss"); return a.exec(); }
  工程文件:QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = TitleBarDemo TEMPLATE = app # The following define makes your compiler emit warnings if you use # any feature of Qt which has been marked as deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES +=  main.cpp  TitleBar.cpp  QWindowBase.cpp HEADERS +=  TitleBar.h  CommonHelper.h  QWindowBase.h RESOURCES +=  TitileBarDemo.qrc
  工程目录结构:
  3、自定义窗体基类结果展示
  运行结果:

大衣直筒裤怎么穿更高级?送你3个搭配思路,又美又飒又显高前面我们说了很多大衣半身裙的搭配,今天就来聊聊大衣直筒裤的穿搭方式。相对于前者来说,后者更加保暖防风,而相比于大衣阔腿裤,大衣直筒裤还能打造出利落高级感,非常适合小个子。那么,我们这些穿搭雷区难道你还在踩我就是爱穿紧身裤,谁也别拦我谁不希望自己的腿能够细一点,再细一点呢,于是,紧身牛仔裤这一伟大的发明就应运而生了。但是!!!你以为紧身牛仔裤谁穿都好看吗本来就不直的腿显得更弯了看看这关于美妆的那些事儿爱美之心,人皆有之。随着生活水平的不断提高,人们也越来越注重保养,追求时尚。护肤品,化妆品等等似乎已经成了绝大部分人中不可或缺的一部分。琳琅满目的化妆品也是让我们眼花缭乱,也不知道女排名将张常宁手术成功,有望满血归来今天,女排队员张常宁发文报平安,手术成功进行,目前正在恢复!张常宁的膝盖从2018年就一直有伤,之前带着沉重的护具比赛。被称为钢铁侠,在今年女排联赛中伤病反复,东奥会之后,全运会也朱之文的亲家今天来了,大衣哥却忙着给转转锅做代言朱之文的亲家今天来了,大衣哥却忙着给转转锅做代言。最近大衣哥有多忙,电视台邀请大衣哥做节目,大衣哥马不停蹄赶往节目现场,然后参加代言活动,回到朱楼村之后,也是疲惫不已,有消息称,朱王俊凯,请把27万元还给粉丝为什么要整治饭圈文化?为什么要禁止粉丝应援?我就举一个例子,你就明白了。王俊凯的生日,粉丝应援极其夸张!极其奢华!极其浪费!极其莫名其妙!在国内十几个大城市的机场地铁公交商场等场所eNP1首秀广汽本田电动化转型按下加速键为了进一步拉近与用户的距离,广汽本田上线了广汽本田App,同时FunLink创享车生活服务品牌正在扎实推进。久等了!在2021广州国际车展上,当这三个大字出现在广汽本田展台发布会大感恩的话语都藏在这篇文章里感恩学会了感恩,就学会了爱!明天就是感恩节了,这些文案分享给你,愿你步履不停,感恩不止!对大自然01。感谢山河,能容纳我02。感谢自然慷慨,卸下了我负重行囊03。感谢时光,对我不离明月装饰了你的窗子,你装饰了别人的梦那些还没有遇见的美好,会是生命里永远的温柔那个被你温柔的转身,会是生命里永远的不舍,会舍得舍得与珍惜。一夜的风轻轻的吹,一夜的雨悄悄落下,无言的夜。那么轻,柔到能听见你在掌心的汗水曾经的故土,永远留在了我的心里前一阵很大的风儿,经过了许多的辛劳,我终于回到了家乡。走进家门后果然发现有几株枝叶飘落下来,很漂亮,但是它们比我高很多。树高大,枝繁叶茂,过不了多少天,它们又被无情地摧残得掉落下来开国中将,带出韩先楚刘震两位开国上将,曾救徐海东一命,游击陕南令毛泽东刮目相看文杜俊峰陈守凤1914年9月24日,陈先瑞出生于河南省商城县麻河岗大阎家湾村一户贫苦农家。他出生时,家中已有一个哥哥和一个姐姐。由于实在太穷,陈先瑞直到9岁时才被送入私塾读书识字。
建议中老年人无论贫富,多吃5种高卵磷脂食物,早吃早受益人一旦上了年纪,就会觉得身体各项功能都减弱,我们不难发现,很多年纪大一点的人大脑记忆力会衰退,严重的就变成了阿尔茨海默病,也就是俗称的老年痴呆。卵磷脂是人体一种必需的营养物质,又被今日大暑,建议老年人,多吃3种食物,便宜又营养,清爽解暑不腻今日大暑,建议老年人,多吃3种食物,便宜又营养,清爽解暑不腻大暑正值中伏前后,是是一年中阳光最强烈气温最炎热的节气,湿热交蒸在此时到达顶点,所以民间有大暑小暑,上蒸下煮的说法。这个铁矿石大涨8。51焦炭限产50,下周钢材价格上涨导火索被点燃?查询及时钢材价格,请点击众钢网专注钢材价格数据最新消息周五下午新加坡铁矿石指数期货大涨5。26,报收103。1美元吨,再次站上100美元大关。周五夜盘铁矿石期货价格王者归来,暴涨8腾讯或裁撤幻核业务,数字藏品退潮曾一天价格暴涨30倍,如今大厂都带不动本文来源时代财经作者李婷图源Pixabay一串独一无二的编号,代表着一份只属于你自己的数字藏品。它可能是一件衣服,也可能是一幅世界名画的数字映射。近年来,元宇宙概念火热,在区块链技新一代颜值天花板魅族19Pro来了,价格有点贵?丨欧界欧界报道我们平时购买手机时,除了关注手机处理器及整体性能怎么样,还会简单休息一下手机颜值如何。纵观现在的手机市场,颜值最高莫过于纯白色面板纯白机身的魅族手机了,这一颜值是非常稀缺的iPhone14即将量产,升级亮点还要看Pro版,价格更贵苹果去年的iPhone13系列手机有四款不同的机型,分别为iPhone13mini,iPhone13,iPhone13Pro及iPhone13Promax。在iPhone13系列手大暑后,我家经常喝这汤,简单易学,营养极高,安稳度过夏季时光冉冉,转眼就要迎来大暑节气,介于小暑和三伏天之间,这个时候是夏季最炎热的时候,天气非常湿热,我们只要稍微走动,都会全身都流汗,每天像在蒸桑拿一样,嗓子非常不舒服,浑身都不舒服,一个月业绩暴增400!这种钻石,卖爆了!价格为天然钻石13来源央视财经培育钻石,也叫人造钻石,是实验室培育出来的真钻石。最近,包括力量钻石中兵红箭四方达等在内的多个培育钻石上市公司发布半年度业绩预告,业绩大幅预增。那么,培育钻石最近的销售简单度日,淡然处世幸福,不取决于你外在物质的丰富程度,只取决于你内心世界的富足与否一个内心富足的人,即使在最简单的事物中,也能发现不一样的美即使在平淡的生活中,也能活出不一样的光芒。人很多时候,都是胆小易惊?气不足?送你3味药,益肝利胆振奋心肾治心胆气虚大家好,我是屈医生。你有没有这样的情况?胆子特别小,稍微遇到点事,心脏就会扑通扑通的跳出一身虚汗,受到惊吓到晚上睡觉的时候,想东想西害怕的睡不着,即便是睡着了,也很容易被惊醒,这是名师说教育的原点是育人,育人的本质是育心,育心的关键在育脑罗清红谈教育20句本文内容节选自成都市教育科学研究院院长罗清红的著作智能时代的共享教育,本书基于信息化手段,以敬畏讲台,深耕课堂,让每一个孩子能自由享受优质教育服务,让每一个孩子发声为核心议题,由四