Qt在win10自定义标题栏,应用主题颜色到标题栏
前言
Qt自定义标题栏的资料很多了,但是百度来github去,没找到应用win10的主题颜色到标题栏,就自己折腾了一下。弄了个Demo。没什么技术含量,献丑了。
先看效果




截图中实现了标题栏颜色和拖动改变窗口位置。
关键点
QtWin
在.pro文件中加入
QT += winextras
就可以使用QtWin命名空间中的API。这里我们使用
QColor QtWin::realColorizationColor()
根据文档描述:

这玩意儿返回的是带有Alpha的标题栏颜色。OK这样就是真实的颜色了。另外一个函数:
QColor QtWin::colorizationColor(bool *opaqueBlend = Q_NULLPTR)
返回的颜色有色差。
注册表获取是否应用了颜色到标题栏
这个东西好像不是公开的,经过我一番折腾,发现了在注册表的这个位置:
HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\DWM
的这个key对应了上面我们开启的“应用颜色到标题栏和窗口边框”

有了这两个东西就好办了,就算是热更改,只需要在需要显示颜色的窗口的绘制事件中绘制上这个颜色就搞定了。
代码
头文件:captionwidget.h
// captionwidget.h
#ifndef CAPTIONWIDGET_H
#define CAPTIONWIDGET_H
#include <QWidget>
#ifdef Q_OS_WIN
class CaptionWidget : public QWidget
{
Q_OBJECT
public:
explicit CaptionWidget(QWidget *parent = 0);
bool event(QEvent *e) override;
signals:
void btnMinClicked();
void btnMaxNormalClicked();
void btnCloseClicked();
void DwmCompsitionChanged();
protected:
// QWidget interface
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;
void paintEvent(QPaintEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void leaveEvent(QEvent *event) override;
private:
enum RectType{
Rect_Other = -1,
Rect_Mini,
Rect_NormalMax,
Rect_Close,
};
enum IconType{
Icon_Mini,
Icon_Max,
Icon_Restore,
Icon_Close,
};
bool mini_hover_;
bool max_hover_;
bool close_hover_;
void setTopLevelWidget();
QRectF getRect(RectType type);
QPixmap getPixmap(IconType type,const QColor &color);
QColor getIconColor(bool isClose = false);
int itemAt(const QPoint &pos);
static QColor getForgroundColor(const QColor &backgroundColor);
/// \brief windows8以上版本,获取是否将主题颜色应用到标题栏和边框
/// \return
///
static bool dwmColorPrevalence();
};
#else
class CaptionWidget : public QWidget
{
Q_OBJECT
public:
CaptionWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
: QWidget(parent, f)
{
}
};
#endif // Q_OS_WIN
#endif // CAPTIONWIDGET_H
源文件:captionwidget.cpp
// captionwidget.cpp
#include "captionwidget.h"
#include <QSettings>
#include <QtGlobal>
#ifdef Q_OS_WIN
#include <QPaintEvent>
#include <QMouseEvent>
#include <QHelpEvent>
#include <QPainter>
#include <QtDebug>
#include <QToolTip>
#include <QtWin>
#include <QToolTip>
#include <QStyle>
#include <Windows.h>
#pragma comment(lib, "User32.lib")
CaptionWidget::CaptionWidget(QWidget *parent)
: QWidget(parent)
, mini_hover_(false)
, max_hover_(false)
, close_hover_(false)
{
setMouseTracking(true);
setTopLevelWidget();
}
void CaptionWidget::setTopLevelWidget()
{
auto w = this->window();
connect(this, &CaptionWidget::btnMinClicked, w, &QWidget::showMinimized);
connect(this, &CaptionWidget::btnMaxNormalClicked, w, [=](){
auto state = w->windowState();
if(state.testFlag(Qt::WindowMaximized)){
w->showNormal();
}else if(state.testFlag(Qt::WindowNoState)){
w->showMaximized();
}
});
connect(this, &CaptionWidget::btnCloseClicked, w, &QWidget::close);
}
/// QWidget在鼠标移动后停留的短暂时间内,会触发一次QEvent::ToolTip
/// 如果自绘制的按钮,可以在event中显示tooltip
bool CaptionWidget::event(QEvent *e)
{
if (e->type() == QEvent::ToolTip) {
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(e);
int index = itemAt(helpEvent->pos());
if (index != -1) {
QString str;
switch (index) {
case Rect_Mini:
str = tr("minimize");
break;
case Rect_NormalMax:
str = this->window()-

本文介绍如何在Qt中为应用程序自定义标题栏,并应用Windows 10的主题颜色。通过使用QtWin API,实现标题栏颜色跟随系统主题变化,并提供最小化、最大化/还原及关闭按钮的功能。
最低0.47元/天 解锁文章
1171





