2026-05-18 19:12:28 +08:00
|
|
|
|
#include "titleBar.h"
|
|
|
|
|
|
#include <QStyle>
|
|
|
|
|
|
#include <QScreen>
|
|
|
|
|
|
#include <QGuiApplication>
|
2026-05-20 16:16:49 +08:00
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
#include <QWindow>
|
2026-05-18 19:12:28 +08:00
|
|
|
|
|
|
|
|
|
|
TitleBar::TitleBar(QWidget *parent,bool bClose,bool bMaxMin)
|
|
|
|
|
|
: QWidget(parent)
|
|
|
|
|
|
, m_parentWindow(parent)
|
|
|
|
|
|
,_bShowClose(bClose)
|
|
|
|
|
|
,_bShowMaxMin(bMaxMin)
|
|
|
|
|
|
{
|
|
|
|
|
|
setupUI();
|
|
|
|
|
|
setFixedHeight(25); // 稍微矮一点
|
|
|
|
|
|
|
|
|
|
|
|
setAttribute(Qt::WA_StyledBackground, true); // 启用样式背景
|
|
|
|
|
|
setAttribute(Qt::WA_NoSystemBackground, false);
|
|
|
|
|
|
|
|
|
|
|
|
// 确保有自己的调色板
|
|
|
|
|
|
setAutoFillBackground(true);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用更具体的样式表
|
|
|
|
|
|
QString style = R"(
|
|
|
|
|
|
QWidget {
|
|
|
|
|
|
background: #2c5282;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QLabel {
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QPushButton {
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
min-width: 20px;
|
|
|
|
|
|
min-height: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
)";
|
|
|
|
|
|
|
|
|
|
|
|
setStyleSheet(style);
|
2026-05-19 11:14:04 +08:00
|
|
|
|
|
2026-05-20 16:16:49 +08:00
|
|
|
|
// ✅ 每次 show 都居中
|
2026-05-19 11:14:04 +08:00
|
|
|
|
if (m_parentWindow) {
|
2026-05-20 16:16:49 +08:00
|
|
|
|
connect(m_parentWindow, &QWidget::show,
|
|
|
|
|
|
this, &TitleBar::centerWindowOnce);
|
2026-05-19 11:14:04 +08:00
|
|
|
|
}
|
2026-05-18 19:12:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::setupUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout(this);
|
|
|
|
|
|
layout->setContentsMargins(4, 0, 0, 0);
|
|
|
|
|
|
layout->setSpacing(0);
|
|
|
|
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
|
|
m_titleLabel = new QLabel("窗口标题");
|
|
|
|
|
|
m_titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
|
|
|
|
|
|
|
|
|
|
layout->addWidget(m_titleLabel);
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== 中间占位,用于居中 ===== */
|
|
|
|
|
|
layout->addStretch();
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== 中间内容 Label ===== */
|
|
|
|
|
|
m_centerLabel = new QLabel();
|
|
|
|
|
|
m_centerLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
|
m_centerLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
|
|
|
|
|
|
|
|
|
|
layout->addWidget(m_centerLabel);
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== 右侧占位 ===== */
|
|
|
|
|
|
layout->addStretch();
|
|
|
|
|
|
|
|
|
|
|
|
if(_bShowMaxMin){
|
|
|
|
|
|
// 最大化/还原按钮
|
|
|
|
|
|
m_maximizeButton = new QPushButton(tr("🗖")); // 最大化图标
|
|
|
|
|
|
m_maximizeButton->setObjectName("maximizeButton");
|
|
|
|
|
|
m_maximizeButton->setToolTip("最大化");
|
|
|
|
|
|
|
|
|
|
|
|
layout->addWidget(m_maximizeButton);
|
|
|
|
|
|
connect(m_maximizeButton, &QPushButton::clicked, this, &TitleBar::maximizeClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(_bShowClose){
|
|
|
|
|
|
// 关闭按钮
|
|
|
|
|
|
m_closeButton = new QPushButton("×");
|
|
|
|
|
|
m_closeButton->setObjectName("closeButton");
|
|
|
|
|
|
m_closeButton->setToolTip("关闭");
|
|
|
|
|
|
|
|
|
|
|
|
layout->addWidget(m_closeButton);
|
|
|
|
|
|
connect(m_closeButton, &QPushButton::clicked, this, &TitleBar::closeClicked);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 16:16:49 +08:00
|
|
|
|
void TitleBar::centerWindowOnce()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_parentWindow)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_parentWindow->isMaximized() ||
|
|
|
|
|
|
m_parentWindow->isFullScreen())
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
|
QTimer::singleShot(0, this, [this] {
|
|
|
|
|
|
QScreen *screen = m_parentWindow->screen();
|
|
|
|
|
|
if (!screen)
|
|
|
|
|
|
screen = QGuiApplication::primaryScreen();
|
|
|
|
|
|
if (!screen)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
QRect screenRect = screen->availableGeometry();
|
|
|
|
|
|
QRect windowRect = m_parentWindow->geometry();
|
|
|
|
|
|
|
|
|
|
|
|
m_parentWindow->move(
|
|
|
|
|
|
screenRect.center() - windowRect.center()
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(Q_OS_MACOS)
|
|
|
|
|
|
QTimer::singleShot(0, this, [this] {
|
|
|
|
|
|
QScreen *screen = m_parentWindow->screen();
|
|
|
|
|
|
if (!screen)
|
|
|
|
|
|
screen = QGuiApplication::primaryScreen();
|
|
|
|
|
|
if (!screen)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
QRect screenRect = screen->availableGeometry();
|
|
|
|
|
|
QRect windowRect = m_parentWindow->geometry();
|
|
|
|
|
|
|
|
|
|
|
|
m_parentWindow->move(
|
|
|
|
|
|
screenRect.center() - windowRect.center()
|
|
|
|
|
|
);
|
|
|
|
|
|
});
|
|
|
|
|
|
#endif
|
|
|
|
|
|
// ✅ Linux:什么都不做,交给窗口管理器
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-18 19:12:28 +08:00
|
|
|
|
void TitleBar::setTitle(const QString &title)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_titleLabel->setText(title);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::setCenterText(const QString &text)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_centerLabel)
|
|
|
|
|
|
m_centerLabel->setText(text);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::updateMaximizeButton()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(_bShowMaxMin){
|
|
|
|
|
|
if (m_parentWindow) {
|
|
|
|
|
|
m_isMaximized = m_parentWindow->isMaximized();
|
|
|
|
|
|
if (m_isMaximized) {
|
|
|
|
|
|
m_maximizeButton->setText(tr("🗗")); // 还原图标
|
|
|
|
|
|
m_maximizeButton->setToolTip("还原");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
m_maximizeButton->setText(tr("🗖")); // 最大化图标
|
|
|
|
|
|
m_maximizeButton->setToolTip("最大化");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::mousePressEvent(QMouseEvent *event)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
2026-05-20 16:16:49 +08:00
|
|
|
|
m_dragStartPosition = event->pos();
|
2026-05-18 19:12:28 +08:00
|
|
|
|
event->accept();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
|
{
|
2026-05-20 16:16:49 +08:00
|
|
|
|
if (!(event->buttons() & Qt::LeftButton))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
|
m_parentWindow->move(
|
|
|
|
|
|
m_parentWindow->pos() +
|
|
|
|
|
|
(event->pos() - m_dragStartPosition)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(Q_OS_MACOS)
|
|
|
|
|
|
// ✅ macOS:Qt 原生拖拽
|
|
|
|
|
|
m_parentWindow->move(
|
|
|
|
|
|
m_parentWindow->pos() +
|
|
|
|
|
|
(event->pos() - m_dragStartPosition)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
#elif defined(Q_OS_LINUX)
|
|
|
|
|
|
QWindow *win = m_parentWindow->windowHandle();
|
|
|
|
|
|
if (win && win->handle()) {
|
|
|
|
|
|
win->startSystemMove();
|
2026-05-18 19:12:28 +08:00
|
|
|
|
}
|
2026-05-20 16:16:49 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
event->accept();
|
2026-05-18 19:12:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
|
|
|
|
emit maximizeClicked();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|