1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Qt自定义标题栏

Qt自定义标题栏

时间:2019-05-11 00:06:26

相关推荐

Qt自定义标题栏

第一次写博客。刚发布出来,发现格式不满意就删了,结果回来看,保存的也没了,真伤。还好有个回收箱,又复制了一遍。

话不多上,先上效果图:

图片效果是加上了样式与透明效果。这里只讲标题栏的创建方法,透明效果与样式我会在下一次介绍。为了让大家能够看清楚效果,上图是我以桌面作为背景。

相信大家可能已经查了很多资料,或者说刚看到我的这篇博客,不过都没关系,因为,看完我这篇,你们这个问题就可以解决了。大家每次本来把样式整的漂漂亮亮的,却因为系统的自带标题栏,导致整个程序页面的美感多了一点瑕疵。

自定义标题栏不仅可以让我们自由在标题栏上添加东西,更方便设计主题,如下面的QQ音乐页面。下面介绍自定义标题栏的三种方法,第一二种方法只介绍思路,详细会介绍第三种方法,也是我目前认为比较好的方法:

第一种:

1.去掉系统自带的标题栏。

2.在界面文件中,用控件在界面顶部布局一个标题栏。

这种方法优点是方便样式的设置,能更好的设置主题,而且设计起来也更简单。缺点是每次都要在新创建的工程中重新布局,还要设置变量,非常的麻烦与浪费多余宝贵的时间,如果是MainWindow窗口,这个方法就不能用了。这个方法就不多去介绍了。

第二种方法:

1、创建一个新的QWidget类,将这个QWidget设计成标题栏,然后再将这个QWidget类加到UI界面文件的顶部,这样每次新建工程,只需要将标题栏的.c和.h文件加到工程中,复制使用代码,就可以加入自定义的标题栏了,非常的方便。但是这个方法缺点是,UI界面的定义必须留一段空的控件放标题栏,与第一种方法有相同的限制,而且遇到MainWindow,会覆盖在菜单栏上,使用代码调整位置也效果不大。这种的负面效果图当时没保存,就不重新花时间弄一遍了。

相信大家查找资料,很多都是第一种第二种方法,而且绝大部分资料都没有考虑MainWindow工程与自己自定的标题栏能不能适用。博主当时查找资料也没有看到满意的资料,我希望能自定义一个标题栏,然后不影响工程的界面文件设计,以后新建工程的时候,能直接把标题栏文件加入工程就可以用了。后来查找资料过程中受到一句话启发,终于完美的解决了这个问题。下面介绍第三种方法。

第三种方法:

第三种方法与第二种方法非常类似。下面介绍思路:

先定义一个新的QWidget类 ,设为TitleBar,将它设计成标题栏。再定义一个新的QWidget类,设为WidgetPar,这个类作为容器,后面说到。然后在创建的工程中的构造函数中,将新建的标题栏类和工程的界面文件做一个整体布局,然后把他们添加到WidgetPar这个类容器中,这样就实现了自定义标题栏。这个方法使得添加标题栏非常方便,不影响原有的UI界面文件设计,而且对界面文件是哪个基类没有任何影响。效果图就是最开始看到的那个了。

设计标题栏就不多介绍了,就是重写事件,将标题栏的那些功能在自定义的标题栏上实现。

下面介绍代码:

titlebar.c和titlebar.h就是标题栏文件。

使用方法,在工程新建一个QWidget类,名字可以取上面一样的,然后将下面的代码复制上去。(类名相同可以全部替换)

titlebar.h

#ifndef TITLEBAR_H#define TITLEBAR_H#include <QWidget>#include <QLabel>#include <QPushButton>/*定义一个新的QWidget类,将标题栏和UI界面都放到这个类里面,定义这个类是为了方便改变主题*/class WidgetPar : public QWidget{Q_OBJECTpublic:explicit WidgetPar(QWidget *parent = 0);signals:public slots://void paintEvent(QPaintEvent *event);};/*自定义的标题栏类*/class TitleBar : public QWidget{Q_OBJECTpublic:explicit TitleBar(QWidget *parent = 0);signals:public slots://右上角三个按钮共用一个槽函数void on_TiBar_Clicked();protected://重写鼠标事件virtual void mouseDoubleClickEvent(QMouseEvent *event);// 双击标题栏进行界面的最大化/还原virtual void mousePressEvent(QMouseEvent *event);// 进行鼠界面的拖动virtual bool eventFilter(QObject *obj, QEvent *event);// 设置界面标题与图标// 标题栏跑马灯效果时钟;//QTimer m_titleRollTimer;private:void updateMaximize();// 最大化/还原private://自定义标题栏控件QLabel *TiBar_pIconLabel;//左上角图标labelQLabel *TiBar_pTitleLabel; //中间标题栏labelQPushButton *TiBar_pMinimizeBtn; //右上角缩小到底部任务栏按钮,最小化QPushButton *TiBar_pMaximizeBtn; //右上角放大缩小按钮QPushButton *TiBar_pCloseBtn; //右上角关闭按钮public:};#endif // TITLEBAR_H

titlebar.c

#include "titlebar.h"#include <QHBoxLayout>#include <QEvent>#include <QMouseEvent>#include <QApplication>#include <qt_windows.h>#include <QPainter>#include <QDebug>TitleBar::TitleBar(QWidget *parent) :QWidget(parent){TiBar_pIconLabel = new QLabel;TiBar_pTitleLabel = new QLabel;TiBar_pMinimizeBtn = new QPushButton;TiBar_pMaximizeBtn = new QPushButton;TiBar_pCloseBtn= new QPushButton;TiBar_pIconLabel->setFixedSize(32, 32); //设置图标固定大小TiBar_pIconLabel->setScaledContents(true); //设置图片显示合适大小TiBar_pTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);//此属性保存窗口小部件的默认布局行为。TiBar_pMinimizeBtn->setFixedSize(32, 32);//设置三个按钮的固定大小TiBar_pMaximizeBtn->setFixedSize(32, 32);TiBar_pCloseBtn->setFixedSize(32, 32);TiBar_pTitleLabel->setFixedHeight(32);TiBar_pMinimizeBtn->setIcon(QIcon(":/image/image/small.ico"));TiBar_pMinimizeBtn->setIconSize(TiBar_pMinimizeBtn->size());TiBar_pMaximizeBtn->setIcon(QIcon(":/image/image/max.ico"));TiBar_pMaximizeBtn->setIconSize(TiBar_pMinimizeBtn->size());TiBar_pCloseBtn->setIcon(QIcon(":/image/image/close.ico"));TiBar_pCloseBtn->setIconSize(TiBar_pMinimizeBtn->size());QPixmap icon(":/image/image/lk.ico");TiBar_pIconLabel->setPixmap(icon);//TiBar_pIconLabel->resize(icon.width(),icon.height());TiBar_pTitleLabel->setObjectName("whiteLabel"); //此属性保存此对象的名称。TiBar_pMinimizeBtn->setObjectName("minimizeButton");TiBar_pMaximizeBtn->setObjectName("maximizeButton");TiBar_pCloseBtn->setObjectName("closeButton");TiBar_pMinimizeBtn->setToolTip("最小化"); //鼠标停留在上面的提示TiBar_pMaximizeBtn->setToolTip("放大/缩小");TiBar_pCloseBtn->setToolTip("关闭");QHBoxLayout *pLayout = new QHBoxLayout(this);pLayout->addWidget(TiBar_pIconLabel);//pLayout->addSpacing(5);pLayout->addWidget(TiBar_pTitleLabel);pLayout->addWidget(TiBar_pMinimizeBtn);pLayout->addWidget(TiBar_pMaximizeBtn);pLayout->addWidget(TiBar_pCloseBtn);pLayout->setSpacing(0);//设置控件之间的间距pLayout->setContentsMargins(0, 0, 0, 0);//设置左上右下的边距this->setLayout(pLayout);connect(TiBar_pMinimizeBtn,SIGNAL(clicked()),this,SLOT(on_TiBar_Clicked()));connect(TiBar_pMaximizeBtn,SIGNAL(clicked()),this,SLOT(on_TiBar_Clicked()));connect(TiBar_pCloseBtn,SIGNAL(clicked()),this,SLOT(on_TiBar_Clicked()));}/* 标题栏右上角三个按钮的槽函数*/void TitleBar::on_TiBar_Clicked(){QPushButton *pBtn = qobject_cast<QPushButton *>(sender());//如果在由信号激活的槽中调用,则返回指向发送信号的对象的指针; 否则它返回0./* 返回此窗口小部件的窗口,即具有(或可能具有)窗口系统框架的下一个祖先窗口小部件。 如果窗口小部件是窗口,则返回窗口小部件本身。*/QWidget *pWindow = this->window();if (pWindow->isWindow())//如果窗口小部件是独立窗口,则返回true,否则返回false。{if (pBtn == TiBar_pMinimizeBtn){pWindow->showMinimized();//最小化窗口小部件,作为图标。调用此函数仅影响窗口。}else if (pBtn == TiBar_pMaximizeBtn){pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();//放大缩小}else if (pBtn == TiBar_pCloseBtn){pWindow->close();//关闭窗口}}}void TitleBar::mouseDoubleClickEvent(QMouseEvent *event){Q_UNUSED(event);emit TiBar_pMaximizeBtn->clicked();}void TitleBar::mousePressEvent(QMouseEvent *event){if (ReleaseCapture()){QWidget *pWindow = this->window();if (pWindow->isWindow()){SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);}}event->ignore();}bool TitleBar::eventFilter(QObject *obj, QEvent *event){switch (event->type()){case QEvent::WindowTitleChange:{QWidget *pWidget = qobject_cast<QWidget *>(obj);if (pWidget){TiBar_pTitleLabel->setText(pWidget->windowTitle());return true;}}case QEvent::WindowIconChange:{QWidget *pWidget = qobject_cast<QWidget *>(obj);if (pWidget){QIcon icon = pWidget->windowIcon();TiBar_pIconLabel->setPixmap(icon.pixmap(TiBar_pIconLabel->size()));return true;}}case QEvent::WindowStateChange:case QEvent::Resize://updateMaximize();return true;default:return false;}return QWidget::eventFilter(obj, event);}//窗口大小发生改变void TitleBar::updateMaximize(){QWidget *pWindow = this->window();if (pWindow->isTopLevel()){bool bMaximize = pWindow->isMaximized();if (bMaximize){TiBar_pMaximizeBtn->setToolTip(tr("Restore"));TiBar_pMaximizeBtn->setProperty("maximizeProperty", "restore");}else{TiBar_pMaximizeBtn->setProperty("maximizeProperty", "maximize");TiBar_pMaximizeBtn->setToolTip(tr("Maximize"));}TiBar_pMaximizeBtn->setStyle(QApplication::style());}}WidgetPar::WidgetPar(QWidget *parent) :QWidget(parent){}

mainwindow.cpp

#include <QGridLayout>#include "titlebar.h"ui->setupUi(this);WidgetPar *selMainWidget = new WidgetPar; //创建一个QWidget容器selMainWidget->setWindowFlags(Qt::FramelessWindowHint);//将这个QWidget的边框去掉this->setParent(selMainWidget);//重新设置这个UI界面的父对象为QWidgetTitleBar *pTitleBar = new TitleBar(selMainWidget); //定义一个标题栏类//设置控件样式//selMainWidget->setStyleSheet("background-color:#AFFFFF00");this->installEventFilter(pTitleBar);//安装事件过滤器QGridLayout *pLayout = new QGridLayout();//创建一个整体布局器pLayout->addWidget(pTitleBar); //添加标题栏pLayout->addWidget(this); //添加UI界面pLayout->setSpacing(0); //布局之间的距离pLayout->setContentsMargins(0, 0, 0,0); //布局器的四周边距selMainWidget->setLayout(pLayout); //将这个布局器设置在QWidget上selMainWidget->setAttribute(Qt::WA_TranslucentBackground, true);selMainWidget->setSizePolicy(this->sizePolicy());selMainWidget->setMaximumSize(this->maximumSize());selMainWidget->setMaximumSize(this->maximumSize());this->setWindowTitle("自定义标题栏成功 -----By DS_LK");selMainWidget->show();//显示QWidge 最后添加

大家按照这个方法基本没问题了。QT版本是用的qt5.3的。

参考资料: 一去丶二三里

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。