马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在 Qt 中,利用 Qt::FramelessWindowHint 可以创建无边框窗口,但如许会导致窗口无法拖动,而且系统默认的标题栏按钮(最小化、最大化、关闭)也会消散。本文将介绍如何实现无边框窗口的鼠标拖动功能,并添加自定义最小化、最大化和关闭按钮。
1. 设置无边框窗口
首先,在 MainWindow 的构造函数中移除默认边框:
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- {
- ui->setupUi(this);
-
- // 设置无边框窗口
- setWindowFlags(Qt::FramelessWindowHint);
-
- // 连接按钮信号(最小化、最大化/还原、关闭)
- connect(ui->toolButton_minimize, &QToolButton::clicked, this, &MainWindow::showMinimized);
- connect(ui->toolButton_maximize, &QToolButton::clicked, this, [this]() {
- if (this->isMaximized()) {
- this->showNormal(); // 如果已最大化,则还原
- } else {
- this->showMaximized(); // 否则最大化
- }
- });
- connect(ui->toolButton_close, &QToolButton::clicked, this, &MainWindow::close);
- }
复制代码 这里:
- toolButton_minimize 是最小化按钮
- toolButton_maximize 是最大化/还原切换按钮
- toolButton_close 是关闭按钮
2. 实现窗口拖动功能
由于无边框窗口无法拖动,我们需要手动处理鼠标变乱:
- 在 MainWindow 类中添加成员变量和重写鼠标变乱:
- // MainWindow.h
- protected:
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- private:
- QPoint m_dragPosition; // 记录鼠标按下时的位置
复制代码- // MainWindow.cpp
- void MainWindow::mousePressEvent(QMouseEvent *event)
- {
- if (event->button() == Qt::LeftButton) {
- m_dragPosition = event->globalPos() - frameGeometry().topLeft();
- event->accept();
- }
- QMainWindow::mousePressEvent(event);
- }
- void MainWindow::mouseMoveEvent(QMouseEvent *event)
- {
- if (event->buttons() & Qt::LeftButton) {
- move(event->globalPos() - m_dragPosition); // 移动窗口
- event->accept();
- }
- QMainWindow::mouseMoveEvent(event);
- }
复制代码
- mousePressEvent:当鼠标左键按下时,记载当前鼠标位置相对于窗口左上角的偏移量。
- mouseMoveEvent:当鼠标左键按下并移动时,盘算窗口新位置并移动窗口。
3. 完整代码示例
MainWindow.h
- #include <QMainWindow>
- #include <QMouseEvent>
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = nullptr);
- ~MainWindow();
- protected:
- void mousePressEvent(QMouseEvent *event) override;
- void mouseMoveEvent(QMouseEvent *event) override;
- private:
- Ui::MainWindow *ui;
- QPoint m_dragPosition;
- };
复制代码 MainWindow.cpp
- #include "MainWindow.h"
- #include "ui_MainWindow.h"
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- , ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
- // 设置无边框窗口
- setWindowFlags(Qt::FramelessWindowHint);
-
- // 连接按钮信号
- connect(ui->toolButton_minimize, &QToolButton::clicked, this, &MainWindow::showMinimized);
- connect(ui->toolButton_maximize, &QToolButton::clicked, this, [this]() {
- if (this->isMaximized()) {
- this->showNormal(); // 还原
- } else {
- this->showMaximized(); // 最大化
- }
- });
- connect(ui->toolButton_close, &QToolButton::clicked, this, &MainWindow::close);
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::mousePressEvent(QMouseEvent *event)
- {
- if (event->button() == Qt::LeftButton) {
- m_dragPosition = event->globalPos() - frameGeometry().topLeft();
- event->accept();
- }
- QMainWindow::mousePressEvent(event);
- }
- void MainWindow::mouseMoveEvent(QMouseEvent *event)
- {
- if (event->buttons() & Qt::LeftButton) {
- move(event->globalPos() - m_dragPosition);
- event->accept();
- }
- QMainWindow::mouseMoveEvent(event);
- }
复制代码 4. 效果
- 窗口无边框,可以拖动。
- 点击最小化按钮,窗口最小化到任务栏。
- 点击最大化按钮,窗口全屏;再次点击还原。
- 点击关闭按钮,窗口关闭。
5. 进阶优化
- 限制拖动区域:
如果只想让窗口的某个区域(如标题栏)可拖动,可以修改 mousePressEvent:
- if (event->button() == Qt::LeftButton && ui->titleBarWidget->geometry().contains(event->pos())) {
- m_dragPosition = event->globalPos() - frameGeometry().topLeft();
- event->accept();
- }
复制代码 - 双击最大化/还原:
可以重写 mouseDoubleClickEvent 实现双击标题栏最大化/还原。
- 窗口阴影效果:
利用 QGraphicsDropShadowEffect 让无边框窗口看起来更雅观。
6. 总结
通过重写 mousePressEvent 和 mouseMoveEvent,我们可以实现无边框窗口的拖动功能。结合自定义按钮,可以完全更换系统默认的标题栏,打造更个性化的 UI。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |