微网站的功能,莱州哪有做网站的,东莞设计网站推荐,苏州网站建设招标Qt开发 系列文章 - titles-icons-titlebars#xff08;九#xff09; 目录
前言
一、修改标题
二、添加图标
三、更换标题栏
1.效果演示
2.创建标题栏类
3.定义相关函数
4.使用标题栏类
总结 前言
在我们利用Qt设计软件时#xff0c;经常需要修改窗口标题、更改软…Qt开发 系列文章 - titles-icons-titlebars九 目录
前言
一、修改标题
二、添加图标
三、更换标题栏
1.效果演示
2.创建标题栏类
3.定义相关函数
4.使用标题栏类
总结 前言
在我们利用Qt设计软件时经常需要修改窗口标题、更改软件图标等之类的操作更有甚者需要更换标题栏因为Qt自带的窗口标题栏无法自定义。这时需要用到QIcon类、QPixmap类等等相关基础功能的操作以下是关于如何在不同场景中添加图标、修改标题、更换标题栏自定义标题栏的简单例子。 一、修改标题
本文提供修改软件窗口标题的方式有两种。
第一种直接在软件初始化函数即构造函数添加如下代码。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);this-setWindowTitle(我的窗口);
}
第二种打开项目可视化UI设计界面在上面进行修改如下图所示。 以上两种方法修改完后编译运行会看到显示如下。 二、添加图标 添加图标的方式有多种本文提供如下几种供参考。不管有几种实现方式首先第一步是先把有图标的文件添加本项目路劲下面。 第一种方式打开项目pro文件添加如下代码。
win32:RC_ICONS $$PWD/ico/A_tubiao.ico
第二种方式在软件初始化函数即构造函数添加如下代码。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);this-setWindowTitle(我的窗口);this-setWindowIcon(QIcon(QDir::currentPath() /ico/A_tubiao.ico));
}
第三种方式打开项目可视化UI设计界面在上面进行修改如下图所示。 上面添加完后会有如下显示说明添加成功。 以上几种方法修改完后编译运行会看到显示如下。 三、更换标题栏
Qt是一个跨平台的框架它旨在提供在不同操作系统上都能保持一致的用户界面体验。Qt自带的窗口标题栏通常遵循操作系统的默认样式和布局以确保在不同平台上都能提供一致且符合用户期望的用户体验因此Qt自带的窗口标题栏无法自定义。
尽管Qt自带的窗口标题栏无法自定义但可以通过一些方法来实现自定义标题栏的效果。例如可以隐藏系统自带的标题栏通过设置窗口标志Qt::FramelessWindowHint然后自行设计一个包含所需功能如最小化、最大化、关闭按钮等的自定义标题栏。下面本文将提供一种自定义标题栏。
1.效果演示 2.创建标题栏类
在我们原有的项目上添加新的类文件选择C设计类的模版选择如下。 然后定义类的名称为MyTitleBar代码如下示例 #ifndef MYTITLEBAR_H
#define MYTITLEBAR_H#include QWidgetenum ButtonType
{MIN_BUTTON 0, // 最小化和关闭按钮;MIN_MAX_BUTTON , // 最小化、最大化和关闭按钮;ONLY_CLOSE_BUTTON // 只有关闭按钮;
};
class MyTitleBar : public QWidget
{Q_OBJECT
public:MyTitleBar(QWidget *parent);~MyTitleBar();void setBackgroundColor(int r, int g, int b , bool isTransparent false);void setTitleIcon(QString filePath , QSize IconSize QSize(25 , 25));void setTitleContent(QString titleContent , int titleFontSize 9);void setTitleWidth(int width);void setButtonType(ButtonType buttonType);void setTitleRoll();void setWindowBorderWidth(int borderWidth);void saveRestoreInfo(const QPoint point, const QSize size);void getRestoreInfo(QPoint point, QSize size);
private:void paintEvent(QPaintEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void initControl();void initConnections();void loadStyleSheet(const QString qssFile);
signals:void signalchangeStyle(const QString qssFile);void signalButtonMinClicked();void signalButtonRestoreClicked();void signalButtonMaxClicked();void signalButtonCloseClicked();
private slots:void onButtonchangeStyle();void onButtonMinClicked();void onButtonRestoreClicked();void onButtonMaxClicked();void onButtonCloseClicked();void onRollTitle();
private:QLabel* m_pIcon; // 标题栏图标;QLabel* m_pTitleContent; // 标题栏内容;QToolButton *m_pButtonMenu; // 色彩菜单QPushButton* m_pButtonMin; // 最小化按钮;QPushButton* m_pButtonRestore; // 最大化还原按钮;QPushButton* m_pButtonMax; // 最大化按钮;QPushButton* m_pButtonClose; // 关闭按钮;int m_colorR;int m_colorG;int m_colorB;QPoint m_restorePos;QSize m_restoreSize;bool m_isPressed;QPoint m_startMovePos;QTimer m_titleRollTimer;QString m_titleContent;ButtonType m_buttonType;int m_windowBorderWidth;bool m_isTransparent;
};
#endif // MYTITLEBAR_H3.定义相关函数
上面我们定义标题栏类的头文件下面来说明相关功能函数。
#include mytitlebar.h
#include QHBoxLayout
#include QPainter
#include QFile
#include QMouseEvent
#include QAction
MyTitleBar::MyTitleBar(QWidget *parent): QWidget(parent), m_colorR(0), m_colorG(153), m_colorB(153), m_isPressed(false), m_buttonType(MIN_MAX_BUTTON), m_windowBorderWidth(0), m_isTransparent(false)
{// 初始化;initControl();// 信号槽的绑定;initConnections();// 加载本地样式 MyTitle.css文件;//loadStyleSheet(MyTitle);
}
// 初始化控件;
void MyTitleBar::initControl()
{// 定义按键变量m_pIcon new QLabel;m_pTitleContent new QLabel;m_pButtonMenu new QToolButton;m_pButtonMin new QPushButton;m_pButtonRestore new QPushButton;m_pButtonMax new QPushButton;m_pButtonClose new QPushButton;QSizePolicy sizePolicy3(QSizePolicy::Fixed, QSizePolicy::Expanding);sizePolicy3.setHorizontalStretch(0);sizePolicy3.setVerticalStretch(0);sizePolicy3.setHeightForWidth(m_pButtonMenu-sizePolicy().hasHeightForWidth());m_pButtonMenu-setSizePolicy(sizePolicy3);m_pButtonMenu-setMinimumSize(QSize(30, 0));m_pButtonMenu-setMaximumSize(QSize(30, 16777215));m_pButtonMenu-setFocusPolicy(Qt::NoFocus);m_pButtonMenu-setPopupMode(QToolButton::InstantPopup);// 设置按键大小m_pButtonMin-setFixedSize(QSize(30, 30));m_pButtonRestore-setFixedSize(QSize(30, 30));m_pButtonMax-setFixedSize(QSize(30, 30));m_pButtonClose-setFixedSize(QSize(30, 30));// 设置名称m_pTitleContent-setObjectName(TitleContent);m_pButtonMenu-setObjectName(btnMenu);m_pButtonMin-setObjectName(ButtonMin);m_pButtonRestore-setObjectName(ButtonRestore);m_pButtonMax-setObjectName(ButtonMax);m_pButtonClose-setObjectName(ButtonClose);// 设置名称m_pButtonMenu-setToolTip(QStringLiteral(菜单));m_pButtonMin-setToolTip(QStringLiteral(最小化));m_pButtonRestore-setToolTip(QStringLiteral(还原));m_pButtonMax-setToolTip(QStringLiteral(最大化));m_pButtonClose-setToolTip(QStringLiteral(关闭));// 定义图标QIcon icon,icon1;// 设置菜单图标icon.addFile(QString(ico/branch_menu.png), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMenu-setIcon(icon);// 设置关闭图标icon1.addFile(QString(ico/branch_close.png), QSize(), QIcon::Normal, QIcon::Off);m_pButtonClose-setIcon(icon1);// 设置最小化图标icon.addFile(QString(ico/branch_min.png), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMin-setIcon(icon);// 设置最大化图标icon.addFile(QString(ico/branch_max.png), QSize(), QIcon::Normal, QIcon::Off);m_pButtonMax-setIcon(icon);// 设置还原图标icon.addFile(QString(ico/branch_res.png), QSize(), QIcon::Normal, QIcon::Off);m_pButtonRestore-setIcon(icon);// 创建Layout框QHBoxLayout* mylayout new QHBoxLayout(this);mylayout-addWidget(m_pIcon);mylayout-addWidget(m_pTitleContent);mylayout-addWidget(m_pButtonMenu);mylayout-addWidget(m_pButtonMin);mylayout-addWidget(m_pButtonRestore);mylayout-addWidget(m_pButtonMax);mylayout-addWidget(m_pButtonClose);// 设置Layout框格式mylayout-setContentsMargins(5, 0, 0, 0);mylayout-setSpacing(0);// 设置标题栏内容大小m_pTitleContent-setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);this-setFixedHeight(TITLE_HEIGHT);this-setWindowFlags(Qt::FramelessWindowHint);// 添加换肤菜单QStringList name;name 蓝色 浅蓝色 灰色 浅灰色 浅黑色 浅紫色 橙色;foreach (QString str, name) {QAction *action new QAction(str, this);this-m_pButtonMenu-addAction(action);connect(action, SIGNAL(triggered(bool)), this, SLOT(onButtonchangeStyle()));}
}
// 信号槽的绑定;
void MyTitleBar::initConnections()
{connect(m_pButtonMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));connect(m_pButtonRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));connect(m_pButtonMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}
// 以下为按钮操作响应的槽
void MyTitleBar::onButtonchangeStyle()
{QAction *act (QAction *)sender();QString name act-text();QString qssFile qss/blue.css;if (name 蓝色)qssFile qss/blue.css;else if (name 浅蓝色)qssFile qss/lightblue.css;else if (name 灰色)qssFile qss/flatgray.css;else if (name 浅灰色)qssFile qss/lightgray.css;else if (name 浅黑色)qssFile qss/blacksoft.css;else if (name 浅紫色)qssFile qss/purple.css;else if (name 橙色)qssFile qss/orange.css;loadStyleSheet(qssFile);emit signalchangeStyle(qssFile);
}
void MyTitleBar::onButtonMinClicked()
{emit signalButtonMinClicked();
}
void MyTitleBar::onButtonRestoreClicked()
{m_pButtonRestore-setVisible(false);m_pButtonMax-setVisible(true);emit signalButtonRestoreClicked();
}
void MyTitleBar::onButtonMaxClicked()
{m_pButtonMax-setVisible(false);m_pButtonRestore-setVisible(true);emit signalButtonMaxClicked();
}
void MyTitleBar::onButtonCloseClicked()
{emit signalButtonCloseClicked();
}// 加载本地样式文件;
// 可以将样式直接写在文件中程序运行时直接加载进来;
void MyTitleBar::loadStyleSheet(const QString qssFile)
{QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss this-styleSheet();qss QLatin1String(file.readAll());this-setStyleSheet(qss);file.close();}
}
// 设置标题栏背景色,在paintEvent事件中进行绘制标题栏背景色;
// 在构造函数中给了默认值可以外部设置颜色值改变标题栏背景色;
void MyTitleBar::setBackgroundColor(int r, int g, int b, bool isTransparent)
{m_colorR r;m_colorG g;m_colorB b;m_isTransparent isTransparent;// 重新绘制调用paintEvent事件;update();
}
// 设置标题栏图标;
void MyTitleBar::setTitleIcon(QString filePath, QSize IconSize)
{QPixmap titleIcon(filePath);m_pIcon-setPixmap(titleIcon.scaled(IconSize));
}
void MyTitleBar::setTitleContent(QString titleContent, int titleFontSize)
{// 设置标题字体大小;QFont font m_pTitleContent-font();font.setPointSize(titleFontSize);m_pTitleContent-setFont(font);// 设置标题内容;m_pTitleContent-setText(titleContent);m_titleContent titleContent;
}// 设置标题栏长度;
void MyTitleBar::setTitleWidth(int width)
{this-setFixedWidth(width);
}// 设置标题栏上按钮类型;
// 由于不同窗口标题栏上的按钮都不一样所以可以自定义标题栏中的按钮;
// 这里提供了四个按钮分别为最小化、还原、最大化、关闭按钮如果需要其他按钮可自行添加设置;
void MyTitleBar::setButtonType(ButtonType buttonType)
{m_buttonType buttonType;switch (buttonType){case MIN_BUTTON:{m_pButtonRestore-setVisible(false);m_pButtonMax-setVisible(false);}break;case MIN_MAX_BUTTON:{m_pButtonRestore-setVisible(false);}break;case ONLY_CLOSE_BUTTON:{m_pButtonMin-setVisible(false);m_pButtonRestore-setVisible(false);m_pButtonMax-setVisible(false);}break;default:break;}
}// 设置标题栏中的标题是否会自动滚动;
// 一般情况下标题栏中的标题内容是不滚动的但是既然自定义就看自己需要嘛想怎么设计就怎么搞O(∩_∩)O
void MyTitleBar::setTitleRoll()
{connect(m_titleRollTimer, SIGNAL(timeout()), this, SLOT(onRollTitle()));m_titleRollTimer.start(200);
}// 设置窗口边框宽度;
void MyTitleBar::setWindowBorderWidth(int borderWidth)
{m_windowBorderWidth borderWidth;
}
// 保存窗口最大化前窗口的位置以及大小;
void MyTitleBar::saveRestoreInfo(const QPoint point, const QSize size)
{m_restorePos point;m_restoreSize size;
}// 获取窗口最大化前窗口的位置以及大小;
void MyTitleBar::getRestoreInfo(QPoint point, QSize size)
{point m_restorePos;size m_restoreSize;
}
// 绘制标题栏背景色;
void MyTitleBar::paintEvent(QPaintEvent *event)
{// 是否设置标题透明;if (!m_isTransparent){//设置背景色;QPainter painter(this);QPainterPath pathBack;pathBack.setFillRule(Qt::WindingFill);pathBack.addRoundedRect(QRect(0, 0, this-width(), this-height()), 3, 3);painter.setRenderHint(QPainter::Antialiasing, true);painter.fillPath(pathBack, QBrush(QColor(m_colorR, m_colorG, m_colorB)));}// 当窗口最大化或者还原后窗口长度变了标题栏的长度应当一起改变;// 这里减去m_windowBorderWidth 是因为窗口可能设置了不同宽度的边框;// 如果窗口有边框则需要设置m_windowBorderWidth的值否则m_windowBorderWidth默认为0;if (this-width() ! (this-parentWidget()-width() - m_windowBorderWidth)){this-setFixedWidth(this-parentWidget()-width() - m_windowBorderWidth);}QWidget::paintEvent(event);
}// 双击响应事件主要是实现双击标题栏进行最大化和最小化操作;
void MyTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{// 只有存在最大化、还原按钮时双击才有效;if (m_buttonType MIN_MAX_BUTTON){// 通过最大化按钮的状态判断当前窗口是处于最大化还是原始大小状态;// 或者通过单独设置变量来表示当前窗口状态;if (m_pButtonMax-isVisible()){onButtonMaxClicked();}else{onButtonRestoreClicked();}}return QWidget::mouseDoubleClickEvent(event);
}// 以下通过mousePressEvent、mouseMoveEvent、mouseReleaseEvent三个事件实现了鼠标拖动标题栏移动窗口的效果;
void MyTitleBar::mousePressEvent(QMouseEvent *event)
{if (m_buttonType MIN_MAX_BUTTON){// 在窗口最大化时禁止拖动窗口;if (m_pButtonMax-isVisible()){m_isPressed true;m_startMovePos event-globalPos();}}else{m_isPressed true;m_startMovePos event-globalPos();}return QWidget::mousePressEvent(event);
}void MyTitleBar::mouseMoveEvent(QMouseEvent *event)
{if (m_isPressed){QPoint movePoint event-globalPos() - m_startMovePos;QPoint widgetPos this-parentWidget()-pos();m_startMovePos event-globalPos();this-parentWidget()-move(widgetPos.x() movePoint.x(), widgetPos.y() movePoint.y());}return QWidget::mouseMoveEvent(event);
}
void MyTitleBar::mouseReleaseEvent(QMouseEvent *event)
{m_isPressed false;return QWidget::mouseReleaseEvent(event);
}
// 该方法主要是让标题栏中的标题显示为滚动的效果;
void MyTitleBar::onRollTitle()
{static int nPos 0;QString titleContent m_titleContent;// 当截取的位置比字符串长时从头开始;if (nPos titleContent.length())nPos 0;m_pTitleContent-setText(titleContent.mid(nPos));nPos;
}
4.使用标题栏类
在用户的构造函数上面添加对标题栏类的使用主要是设置主窗口MainWindow的去除边框功能通过设置窗口标志Qt::FramelessWindowHint、设置窗口最小化时点击任务栏窗口可以显示出原窗口通过设置窗口标志Qt::WindowMinimizeButtonHint、设置窗口背景透明通过设置窗口标志Qt::WA_TranslucentBackground然后在初始化标题栏类关联标题栏类和主窗口类的相关信号和槽函数实现所需最小化、最大化、关闭按钮等功能并包括对标题栏类图标、标题、大小尺寸等效果设置具体代码如下。
class MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent nullptr);~MainWindow();
private slots:void onButtonchangeStyle(const QString qssFile);void onButtonMinClicked();void onButtonRestoreClicked();void onButtonMaxClicked();void onButtonCloseClicked();
protected:bool eventFilter(QObject *obj, QEvent *event) override;void initTitleBar();void paintEvent(QPaintEvent *event) override;
private:Ui::MainWindow *ui;MyTitleBar* m_titleBar;
};MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);// 设置窗口去除边框 窗口最小化时点击任务栏窗口可以显示出原窗口;this-setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);// 设置窗口背景透明;setAttribute(Qt::WA_TranslucentBackground);// 关闭窗口时释放资源注意如果是主窗口不要设置WA_DeleteOnClose属性//setAttribute(Qt::WA_DeleteOnClose);/*** 初始化标题栏 ***/initTitleBar();/*** 画图界面初始化 ***/InitChart();/*** 注册事件过滤器 ***/ui-widget-installEventFilter(this);ui-tab-installEventFilter(this);ui-tab_2-installEventFilter(this);/*** 创建右键菜单 ***/CreateMenu(ui-widget);CreateMenu(ui-tab);CreateMenu(ui-tab_2);/*** 工具栏影藏 ***/ui-toolBar-hide();
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::initTitleBar()
{m_titleBar new MyTitleBar(this);m_titleBar-move(0, 0);connect(m_titleBar, SIGNAL(signalchangeStyle(QString)), this, SLOT(onButtonchangeStyle(QString)));connect(m_titleBar, SIGNAL(signalButtonMinClicked()), this, SLOT(onButtonMinClicked()));connect(m_titleBar, SIGNAL(signalButtonRestoreClicked()), this, SLOT(onButtonRestoreClicked()));connect(m_titleBar, SIGNAL(signalButtonMaxClicked()), this, SLOT(onButtonMaxClicked()));connect(m_titleBar, SIGNAL(signalButtonCloseClicked()), this, SLOT(onButtonCloseClicked()));// 设置标题栏效果可以不设置;m_titleBar-setTitleRoll();// 设置标题栏图标;m_titleBar-setTitleIcon(QDir::currentPath() /ico/butterfly.ico);m_titleBar-setTitleContent(QStringLiteral(***Qt更改标题栏动态效果测试***));m_titleBar-setButtonType(MIN_MAX_BUTTON);m_titleBar-setTitleWidth(this-width());
}
void MainWindow::onButtonchangeStyle(const QString qssFile)
{QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss this-styleSheet();qss QLatin1String(file.readAll());qApp-setStyleSheet(qss);file.close();}
}
void MainWindow::onButtonMinClicked()
{showMinimized();
}
void MainWindow::onButtonRestoreClicked()
{QPoint windowPos;QSize windowSize;m_titleBar-getRestoreInfo(windowPos, windowSize);this-setGeometry(QRect(windowPos, windowSize));
}
void MainWindow::onButtonMaxClicked()
{m_titleBar-saveRestoreInfo(this-pos(), QSize(this-width(), this-height()));QRect desktopRect QApplication::desktop()-availableGeometry();QRect FactRect QRect(desktopRect.x() - 3, desktopRect.y() - 3, desktopRect.width() 6, desktopRect.height() 6);setGeometry(FactRect);
}
void MainWindow::onButtonCloseClicked()
{close();
}
void MainWindow::paintEvent(QPaintEvent* event)
{//设置背景色;QPainter painter(this);QPainterPath pathBack;pathBack.setFillRule(Qt::WindingFill);pathBack.addRoundedRect(QRect(0, 0, this-width(), this-height()), 3, 3);painter.setRenderHint(QPainter::SmoothPixmapTransform, true);painter.fillPath(pathBack, QBrush(QColor(238, 223, 204)));return QWidget::paintEvent(event);
}
以上是对自定义标题栏的实现一种相关例程附文末当然还有其他实现方式例如更快捷的是通过可视化界面UI来设计标题栏然后绑定/链接到主窗口界面上具体例程可见文末链接处。 总结
博文中相应的工程代码Qt-Case.zip 利用Qt开发软件进行编的例程为博文提供案例-CSDN文库。