【Qt】Qt之自定义界面(添加自定义标题栏)【转】
来源:互联网 发布:jquery javascript 编辑:程序博客网 时间:2024/05/21 06:42
简述
通过上节内容,我们实现了自定义窗体的移动,但是我们缺少一个标题栏来显示窗体的图标、标题,以及控制窗体最小化、最大化、关闭的按钮。
自定义标题栏后,所有的控件我们都可以定制,比如:在标题栏中添加换肤、设置按钮以及其他控件。
- 简述
- 效果
- 自定义标题栏
- 实现
- 接口说明
- 使用方式
效果
自定义标题栏
实现
title_bar.h
#ifndef TITLE_BAR#define TITLE_BAR#include <QWidget>class QLabel;class QPushButton;class TitleBar : public QWidget{ Q_OBJECTpublic: explicit TitleBar(QWidget *parent = 0); ~TitleBar();protected: // 双击标题栏进行界面的最大化/还原 virtual void mouseDoubleClickEvent(QMouseEvent *event); // 进行鼠界面的拖动 virtual void mousePressEvent(QMouseEvent *event); // 设置界面标题与图标 virtual bool eventFilter(QObject *obj, QEvent *event);private slots: // 进行最小化、最大化/还原、关闭操作 void onClicked();private: // 最大化/还原 void updateMaximize();private: QLabel *m_pIconLabel; QLabel *m_pTitleLabel; QPushButton *m_pMinimizeButton; QPushButton *m_pMaximizeButton; QPushButton *m_pCloseButton;};#endif // TITLE_BAR
title_bar.cpp
#include <QLabel>#include <QPushButton>#include <QHBoxLayout>#include <QEvent>#include <QMouseEvent>#include <QApplication>#include "title_bar.h"#ifdef Q_OS_WIN#pragma comment(lib, "user32.lib")#include <qt_windows.h>#endifTitleBar::TitleBar(QWidget *parent) : QWidget(parent){ setFixedHeight(30); m_pIconLabel = new QLabel(this); m_pTitleLabel = new QLabel(this); m_pMinimizeButton = new QPushButton(this); m_pMaximizeButton = new QPushButton(this); m_pCloseButton = new QPushButton(this); m_pIconLabel->setFixedSize(20, 20); m_pIconLabel->setScaledContents(true); m_pTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); m_pMinimizeButton->setFixedSize(27, 22); m_pMaximizeButton->setFixedSize(27, 22); m_pCloseButton->setFixedSize(27, 22); m_pTitleLabel->setObjectName("whiteLabel"); m_pMinimizeButton->setObjectName("minimizeButton"); m_pMaximizeButton->setObjectName("maximizeButton"); m_pCloseButton->setObjectName("closeButton"); m_pMinimizeButton->setToolTip("Minimize"); m_pMaximizeButton->setToolTip("Maximize"); m_pCloseButton->setToolTip("Close"); QHBoxLayout *pLayout = new QHBoxLayout(this); pLayout->addWidget(m_pIconLabel); pLayout->addSpacing(5); pLayout->addWidget(m_pTitleLabel); pLayout->addWidget(m_pMinimizeButton); pLayout->addWidget(m_pMaximizeButton); pLayout->addWidget(m_pCloseButton); pLayout->setSpacing(0); pLayout->setContentsMargins(5, 0, 5, 0); setLayout(pLayout); connect(m_pMinimizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(m_pMaximizeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(m_pCloseButton, SIGNAL(clicked(bool)), this, SLOT(onClicked()));}TitleBar::~TitleBar(){}void TitleBar::mouseDoubleClickEvent(QMouseEvent *event){ Q_UNUSED(event); emit m_pMaximizeButton->clicked();}void TitleBar::mousePressEvent(QMouseEvent *event){#ifdef Q_OS_WIN if (ReleaseCapture()) { QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); } } event->ignore();#else#endif}bool TitleBar::eventFilter(QObject *obj, QEvent *event){ switch (event->type()) { case QEvent::WindowTitleChange: { QWidget *pWidget = qobject_cast<QWidget *>(obj); if (pWidget) { m_pTitleLabel->setText(pWidget->windowTitle()); return true; } } case QEvent::WindowIconChange: { QWidget *pWidget = qobject_cast<QWidget *>(obj); if (pWidget) { QIcon icon = pWidget->windowIcon(); m_pIconLabel->setPixmap(icon.pixmap(m_pIconLabel->size())); return true; } } case QEvent::WindowStateChange: case QEvent::Resize: updateMaximize(); return true; } return QWidget::eventFilter(obj, event);}void TitleBar::onClicked(){ QPushButton *pButton = qobject_cast<QPushButton *>(sender()); QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { if (pButton == m_pMinimizeButton) { pWindow->showMinimized(); } else if (pButton == m_pMaximizeButton) { pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized(); } else if (pButton == m_pCloseButton) { pWindow->close(); } }}void TitleBar::updateMaximize(){ QWidget *pWindow = this->window(); if (pWindow->isTopLevel()) { bool bMaximize = pWindow->isMaximized(); if (bMaximize) { m_pMaximizeButton->setToolTip(tr("Restore")); m_pMaximizeButton->setProperty("maximizeProperty", "restore"); } else { m_pMaximizeButton->setProperty("maximizeProperty", "maximize"); m_pMaximizeButton->setToolTip(tr("Maximize")); } m_pMaximizeButton->setStyle(QApplication::style()); }}
接口说明
- mousePressEvent
之前,我们将界面移动的事件写在主界面里面,这会有一个问题,一般情况下,是界面随着标题栏的移动而移动,而并非界面中的所有位置都可以进行拖动,所以我们将事件写在标题栏中比较合理。
- mouseDoubleClickEvent
双击标题栏会进行窗体的最大化/还原,所以我们需要重写此事件进行控制。
eventFilter
事件过滤器,这里被监听的窗体为标题栏所在的窗体,所以当窗体标题、图标等信息发生改变时,标题栏也应该随之改变。
最好不要通过直接调用接口的形式来操作对应的行为,比如:TitleBar中定义一个public函数来专门修改标题与图标,这样会造成不必要的麻烦,因为Qt本身就是基于事件的,所以此处采用过滤器的方式。
updateMaximize
因为窗体大小发生变化的时候,最大化的图标、提示应该对应的发生变化,所以在eventFilter中事件触发时调用。
使用方式
Widget::Widget(QWidget *parent) : QWidget(parent){ setWindowFlags(Qt::FramelessWindowHint | windowFlags()); TitleBar *pTitleBar = new TitleBar(this); installEventFilter(pTitleBar); resize(400, 300); setWindowTitle("Custom Window"); setWindowIcon(QIcon(":/Images/logo")); QPalette pal(palette()); pal.setColor(QPalette::Background, QColor(50, 50, 50)); setAutoFillBackground(true); setPalette(pal); QVBoxLayout *pLayout = new QVBoxLayout(); pLayout->addWidget(pTitleBar); pLayout->addStretch(); pLayout->setSpacing(0); pLayout->setContentsMargins(0, 0, 0, 0); setLayout(pLayout);}
注意
installEventFilter必须在setWindowTitle、setWindowIcon之前调用,因为必须先安装事件过滤器,相应事件触发时,才会进入标题栏的eventFilter事件中。
原文作者:一去丶二三里作者博客:去作者博客空间
0 0
- 【Qt】Qt之自定义界面(添加自定义标题栏)【转】
- Qt之自定义界面(添加自定义标题栏)
- Qt 之 自定义窗口标题栏
- qt之自定义界面
- 【Qt】Qt之自定义界面(窗体缩放)【转】
- 【Qt】Qt之自定义界面(QMessageBox)【转】
- 【Qt】Qt之自定义界面(右下角冒泡)【转】
- Qt之自定义界面添加最小化、关闭按钮、添加背景
- Qt 个性化标题栏,自定义标题栏
- ...Qt实现--自定义标题栏
- 自定义 Qt 窗口标题栏
- QT 自定义标题栏
- qt 自定义标题栏
- Qt 自定义标题栏
- Qt:自定义标题栏(QMainWindow)
- qt创建自定义标题栏
- Qt之自定义界面(窗体缩放)
- Qt之自定义界面(QMessageBox)
- android 开发技巧(5)--使 用 TextSwitcher 实现平滑过渡
- Oracle 11 密码永不过期
- 【Qt】QWidget、QDialog、QMainWindow的异同点【转】
- VB6.0 直接打印 PDF
- 【Qt】Qt之自定义界面(实现无边框、可移动)【转】
- 【Qt】Qt之自定义界面(添加自定义标题栏)【转】
- 把json串中“:”前面名称部分的双引号去掉,值中的双引号保留
- 【Qt】Qt之自定义界面(窗体缩放)【转】
- 前端向后台服务器端发送请求并且传送数据的方式
- 【Qt】Qt之自定义界面(窗体缩放-跨平台终极版)【转】
- 【WinForm】线程中向listview添加数据
- JavaScript奇技淫巧45招
- 【Qt】Qt之自定义界面(QMessageBox)【转】
- 【Qt】Qt之进程间通信(IPC)【转】