QT无边框窗口
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
作为独立组件,多个窗口可复用。