日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt自定义标题栏

發布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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_OBJECT public:explicit WidgetPar(QWidget *parent = 0);signals:public slots://void paintEvent(QPaintEvent *event); };/* 自定義的標題欄類 */ class TitleBar : public QWidget {Q_OBJECT public: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的。

參考資料: 一去丶二三里

總結

以上是生活随笔為你收集整理的Qt自定义标题栏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。