【问题标题】:QT Moving entire window/application by clicking on the menubar c++QT通过单击菜单栏c ++移动整个窗口/应用程序
【发布时间】:2026-02-08 18:40:02
【问题描述】:

我想摆脱应用程序的标题和边框,但要做到这一点,我需要能够通过拖动菜单栏来移动窗口。我发现的两种方法是:

void TopMenuBar::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }
}

void TopMenuBar::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        move(event->globalPos() - dragPosition);
        event->accept();
    }
}

但是,如果我把它放在主窗口中,无论你点击什么,它都会移动,如果我把它放在一个自定义的 QMenuBar 中,它只会在窗口内移动菜单栏。我还尝试在对象之间进行一些信号和插槽技巧(例如将 mousePressEvent 保留在 menuBar 中,将 mouseMoveEvent 保留在 MainWindow 中),但趋势是窗口将“跳转”到鼠标指针所在的位置,而不是平滑地移动它。

其他人对此有解决方案吗?

环境是Windows

【问题讨论】:

  • 你需要使用window()->move()来移动整个窗口的小部件。
  • window()->move() 使整个窗口“跳”到鼠标位置,这不是想要的功能。您应该能够顺利拖动它
  • 这不是真的。尝试运行我链接的问题中的示例代码,窗口确实 “跳转”到鼠标位置 .它的移动与使用本机标题栏时一样流畅。这可能是您代码中的另一个问题。
  • 你是对的。我道歉。与我使用的相比,在您链接到的代码中计算鼠标位置与窗口的方式存在差异。它可能会像那样工作。然而,Leontyev 在下面的回答也非常有效:)

标签: c++ qt


【解决方案1】:

这肯定会起作用 - 刚刚检查过。在 MainWindow 构造函数中调用 ui->menuBar->installEventFilter(this);

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->menuBar)
    {
        if (event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent* mouse_event = dynamic_cast<QMouseEvent*>(event);
            if (mouse_event->button() == Qt::LeftButton)
            {
                dragPosition = mouse_event->globalPos() - frameGeometry().topLeft();
                return false;
            }
        }
        else if (event->type() == QEvent::MouseMove)
        {
            QMouseEvent* mouse_event = dynamic_cast<QMouseEvent*>(event);
            if (mouse_event->buttons() & Qt::LeftButton)
            {
                move(mouse_event->globalPos() - dragPosition);
                return false;
            }
        }


    }
    return false;
}

【讨论】:

  • false 总是返回,让菜单栏中的那些小部件被正确按下,而不会被事件过滤器中断。
  • 这行得通!甚至不需要自定义菜单栏类。非常感谢!
最近更新 更多