1. 创建无边框窗口
通过设置窗口标志来去掉边框。
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QWidget>
#include <QtCore/Qt>
class MainWindow : public QMainWindow {
public:
MainWindow() {
// 去掉边框
setWindowFlags(Qt::FramelessWindowHint);
// 设置窗口大小
resize(800, 600);
}
};
2. 创建自定义标题栏
创建一个继承自 QWidget
的类,包含按钮和标题。
#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtCore/Qt>
class CustomTitleBar : public QWidget {
public:
CustomTitleBar(QWidget* parent = nullptr) : QWidget(parent) {
setupUI();
}
private:
void setupUI() {
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
// 标题
QLabel* title = new QLabel(parent()->windowTitle());
layout->addWidget(title);
// 按钮
QPushButton* minBtn = new QPushButton("最小化");
QPushButton* maxBtn = new QPushButton("最大化");
QPushButton* closeBtn = new QPushButton("关闭");
layout->addWidget(minBtn);
layout->addWidget(maxBtn);
layout->addWidget(closeBtn);
// 信号连接
connect(minBtn, &QPushButton::clicked, parent(), &QWidget::showMinimized);
connect(maxBtn, &QPushButton::clicked, parent(), &QWidget::showMaximized);
connect(closeBtn, &QPushButton::clicked, parent(), &QWidget::close);
}
};
3. 处理窗口移动
重写鼠标事件,实现拖动窗口。
#include <QtWidgets/QMainWindow>
#include <QtCore/QPoint>
#include <QtCore/QMouseEvent>
class MainWindow : public QMainWindow {
public:
MainWindow() {
setWindowFlags(Qt::FramelessWindowHint);
resize(800, 600);
// 添加自定义标题栏
CustomTitleBar* titleBar = new CustomTitleBar(this);
setMenuWidget(titleBar); // 将标题栏设置为菜单栏
}
protected:
bool dragging = false;
QPoint dragPos;
void mousePressEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = true;
dragPos = event->globalPos() - pos();
event->accept();
}
}
void mouseMoveEvent(QMouseEvent* event) override {
if (dragging) {
move(event->globalPos() - dragPos);
event->accept();
}
}
void mouseReleaseEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = false;
}
}
};
4. 处理窗口调整大小
重写调整大小事件,确保标题栏正确显示。
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QWidget>
#include <QtCore/QEvent>
class MainWindow : public QMainWindow {
public:
MainWindow() {
setWindowFlags(Qt::FramelessWindowHint);
resize(800, 600);
CustomTitleBar* titleBar = new CustomTitleBar(this);
setMenuWidget(titleBar);
}
protected:
void resizeEvent(QResizeEvent* event) override {
QMainWindow::resizeEvent(event);
// 确保标题栏的大小与窗口一致
if (menuWidget()) {
menuWidget()->setGeometry(QRect(0, 0, width(), menuWidget()->height()));
}
}
};
5. 复用标题栏
将标题栏类作为独立组件,多个窗口可复用。
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QWidget>
#include <QtCore/Qt>
class AnotherWindow : public QMainWindow {
public:
AnotherWindow() {
setWindowFlags(Qt::FramelessWindowHint);
resize(400, 300);
CustomTitleBar* titleBar = new CustomTitleBar(this);
setMenuWidget(titleBar);
}
protected:
bool dragging = false;
QPoint dragPos;
void mousePressEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = true;
dragPos = event->globalPos() - pos();
event->accept();
}
}
void mouseMoveEvent(QMouseEvent* event) override {
if (dragging) {
move(event->globalPos() - dragPos);
event->accept();
}
}
void mouseReleaseEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = false;
}
}
void resizeEvent(QResizeEvent* event) override {
QMainWindow::resizeEvent(event);
if (menuWidget()) {
menuWidget()->setGeometry(QRect(0, 0, width(), menuWidget()->height()));
}
}
};
6. 完整示例代码
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtCore/Qt>
#include <QtCore/QPoint>
#include <QtCore/QMouseEvent>
#include <QtCore/QResizeEvent>
// 自定义标题栏类
class CustomTitleBar : public QWidget {
public:
CustomTitleBar(QWidget* parent = nullptr) : QWidget(parent) {
setupUI();
}
private:
void setupUI() {
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
QLabel* title = new QLabel(parent()->windowTitle());
layout->addWidget(title);
QPushButton* minBtn = new QPushButton("最小化");
QPushButton* maxBtn = new QPushButton("最大化");
QPushButton* closeBtn = new QPushButton("关闭");
layout->addWidget(minBtn);
layout->addWidget(maxBtn);
layout->addWidget(closeBtn);
connect(minBtn, &QPushButton::clicked, parent(), &QWidget::showMinimized);
connect(maxBtn, &QPushButton::clicked, parent(), &QWidget::showMaximized);
connect(closeBtn, &QPushButton::clicked, parent(), &QWidget::close);
}
};
// 主窗口类
class MainWindow : public QMainWindow {
public:
MainWindow() {
setWindowFlags(Qt::FramelessWindowHint);
resize(800, 600);
CustomTitleBar* titleBar = new CustomTitleBar(this);
setMenuWidget(titleBar);
}
protected:
bool dragging = false;
QPoint dragPos;
void mousePressEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = true;
dragPos = event->globalPos() - pos();
event->accept();
}
}
void mouseMoveEvent(QMouseEvent* event) override {
if (dragging) {
move(event->globalPos() - dragPos);
event->accept();
}
}
void mouseReleaseEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = false;
}
}
void resizeEvent(QResizeEvent* event) override {
QMainWindow::resizeEvent(event);
if (menuWidget()) {
menuWidget()->setGeometry(QRect(0, 0, width(), menuWidget()->height()));
}
}
};
// 另一个窗口类
class AnotherWindow : public QMainWindow {
public:
AnotherWindow() {
setWindowFlags(Qt::FramelessWindowHint);
resize(400, 300);
CustomTitleBar* titleBar = new CustomTitleBar(this);
setMenuWidget(titleBar);
}
protected:
bool dragging = false;
QPoint dragPos;
void mousePressEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = true;
dragPos = event->globalPos() - pos();
event->accept();
}
}
void mouseMoveEvent(QMouseEvent* event) override {
if (dragging) {
move(event->globalPos() - dragPos);
event->accept();
}
}
void mouseReleaseEvent(QMouseEvent* event) override {
if (event->button() == Qt::LeftButton) {
dragging = false;
}
}
void resizeEvent(QResizeEvent* event) override {
QMainWindow::resizeEvent(event);
if (menuWidget()) {
menuWidget()->setGeometry(QRect(0, 0, width(), menuWidget()->height()));
}
}
};
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
MainWindow mainWindow;
AnotherWindow anotherWindow;
mainWindow.show();
anotherWindow.show();
return app.exec();
}
7. 功能说明
无边框窗口:通过 setWindowFlags(Qt::FramelessWindowHint)
实现。
- 自定义标题栏:创建
CustomTitleBar
类,包含标题和按钮。 - 窗口移动:重写鼠标事件 (
mousePressEvent
,mouseMoveEvent
,mouseReleaseEvent
) 实现拖动窗口。 - 窗口调整大小:重写
resizeEvent
,确保标题栏正确显示。 - 复用标题栏:
CustomTitleBar
作为独立组件,多个窗口可复用。