当前位置: 首页> 文旅> 酒店 > 使用 Qt 实现自定义拖动窗口

使用 Qt 实现自定义拖动窗口

时间:2025/8/23 18:57:04来源:https://blog.csdn.net/qq_35803412/article/details/140219684 浏览次数:0次

文章目录

      • 如何在 Qt 中实现无标题栏窗口的拖动
        • 准备工作
        • 创建自定义窗口类
        • 使用 `QDialog` 实现拖动功能
        • 详细解释
        • 代码行解释
      • 小结

如何在 Qt 中实现无标题栏窗口的拖动

在许多桌面应用程序中,我们经常需要自定义窗口外观,包括去掉标题栏,使窗口看起来更加现代和美观。然而,去掉标题栏也意味着失去了通过标题栏拖动窗口的功能。在这篇博客中,我将介绍如何在 Qt 中实现鼠标拖动无标题栏窗口的功能。

准备工作

首先,我们需要创建一个基于 QWidgetQDialog 的自定义窗口类。在这个类中,我们将重写鼠标事件处理函数:mousePressEventmouseMoveEventmouseReleaseEvent,以实现拖动功能。

创建自定义窗口类

让我们从创建一个基本的 Qt 应用程序开始,并定义一个 DraggableWidget 类。下面是一个基于 QWidget 的示例:

#include <QApplication>
#include <QWidget>
#include <QMouseEvent>
#include <QDebug>class DraggableWidget : public QWidget
{Q_OBJECTpublic:DraggableWidget(QWidget *parent = nullptr) : QWidget(parent), isDragging(false){// 设置无标题栏窗口setWindowFlag(Qt::FramelessWindowHint);setAttribute(Qt::WA_DeleteOnClose);resize(400, 300); // 设置窗口大小}protected:void mousePressEvent(QMouseEvent *event) override{if (event->button() == Qt::LeftButton) { // 检查是否按下了鼠标左键isDragging = true; // 设置拖动状态为真,表示开始拖动dragPosition = event->globalPos() - frameGeometry().topLeft(); // 记录鼠标按下时的全局位置与窗口左上角位置的差值event->accept(); // 接受事件,防止事件进一步传播}return QWidget::mousePressEvent(event); // 调用基类的 mousePressEvent 以确保默认行为被执行}void mouseMoveEvent(QMouseEvent *event) override{if (isDragging && (event->buttons() & Qt::LeftButton)) { // 检查是否正在拖动并且左键仍然按下move(event->globalPos() - dragPosition); // 计算并设置窗口的新位置event->accept(); // 接受事件,防止事件进一步传播}return QWidget::mouseMoveEvent(event); // 调用基类的 mouseMoveEvent 以确保默认行为被执行}void mouseReleaseEvent(QMouseEvent *event) override{if (event->button() == Qt::LeftButton) { // 检查是否释放了鼠标左键isDragging = false; // 设置拖动状态为假,表示停止拖动event->accept(); // 接受事件,防止事件进一步传播}return QWidget::mouseReleaseEvent(event); // 调用基类的 mouseReleaseEvent 以确保默认行为被执行}private:bool isDragging; // 是否正在拖动QPoint dragPosition; // 记录拖动时鼠标位置和窗口左上角位置的差值
};int main(int argc, char *argv[])
{QApplication app(argc, argv);DraggableWidget window;window.show();return app.exec();
}
使用 QDialog 实现拖动功能

如果您的窗口类是基于 QDialog,实现方式类似。下面是一个基于 QDialog 的示例:

#include "startdialog.h"
#include "ui_startdialog.h"
#include <QMouseEvent>
#include <QDebug>StartDialog::StartDialog(QWidget *parent) :QDialog(parent),ui(new Ui::StartDialog)
{ui->setupUi(this);setWindowFlag(Qt::FramelessWindowHint);setAttribute(Qt::WA_DeleteOnClose);ui->lineEditPwd->setEchoMode(QLineEdit::Password);initialize();
}StartDialog::~StartDialog()
{delete ui;
}void StartDialog::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) { // 检查是否按下了鼠标左键mouse = true; // 设置拖动状态为真,表示开始拖动dragPosition = event->globalPos() - frameGeometry().topLeft(); // 记录鼠标按下时的全局位置与窗口左上角位置的差值event->accept(); // 接受事件,防止事件进一步传播}return QDialog::mousePressEvent(event); // 调用基类的 mousePressEvent 以确保默认行为被执行
}void StartDialog::mouseReleaseEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) { // 检查是否释放了鼠标左键mouse = false; // 设置拖动状态为假,表示停止拖动event->accept(); // 接受事件,防止事件进一步传播}return QDialog::mouseReleaseEvent(event); // 调用基类的 mouseReleaseEvent 以确保默认行为被执行
}void StartDialog::mouseMoveEvent(QMouseEvent *event)
{if (mouse && (event->buttons() & Qt::LeftButton)) { // 检查是否正在拖动并且左键仍然按下move(event->globalPos() - dragPosition); // 计算并设置窗口的新位置event->accept(); // 接受事件,防止事件进一步传播}return QDialog::mouseMoveEvent(event); // 调用基类的 mouseMoveEvent 以确保默认行为被执行
}
详细解释
  1. 设置无标题栏窗口

    • 使用 setWindowFlag(Qt::FramelessWindowHint) 去掉窗口的标题栏。
    • 使用 setAttribute(Qt::WA_DeleteOnClose) 确保窗口关闭时释放资源。
  2. 实现拖动逻辑

    • mousePressEvent 中,检查鼠标左键按下事件,记录按下时的鼠标位置与窗口左上角位置的差值,并标记为拖动状态。
    • mouseMoveEvent 中,检查是否在拖动状态,并根据当前鼠标位置计算窗口的新位置。
    • mouseReleaseEvent 中,检查鼠标左键释放事件,停止拖动状态。
代码行解释
  • dragPosition = event->globalPos() - frameGeometry().topLeft();:计算鼠标按下时的全局位置和窗口左上角位置的差值,这个差值在拖动过程中保持不变,用于计算新的窗口位置。
  • move(event->globalPos() - dragPosition);:根据当前鼠标位置和记录的差值计算窗口的新位置,并移动窗口。
  • event->accept();:接受事件,防止事件进一步传播给其他控件或处理程序。
  • return QDialog::mousePressEvent(event); 和类似的 mouseReleaseEvent 以及 mouseMoveEvent:调用基类的事件处理函数,确保默认行为被执行。

小结

通过重写 mousePressEventmouseMoveEventmouseReleaseEvent 函数,我们可以在没有标题栏的窗口中实现拖动功能。这种方法在需要自定义窗口外观的应用程序中非常有用。

希望这篇博客能帮助您在 Qt 应用程序中实现拖动无标题栏窗口的功能。如果您有任何问题或建议,请在下方留言讨论。感谢您的阅读!

关键字:使用 Qt 实现自定义拖动窗口

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: