检测 QMainWindow / QDialog 的移动结束(Qt 4.8)

Mat*_*ida 3 qt qt4 qdialog qmainwindow qt4.8

I\xe2\x80\x99m 在 X11 上使用 Qt 4.8.3。

\n

我需要知道用户何时结束在屏幕上拖动窗口,\n这是为了读取最终位置并最终启动动画以将窗口位置调整为 \xe2\x80\x9callowed\xe2\x80\x9d 。

\n

我注意到QWidget::moveEvent每个小移动都会调用 ,但这非常不方便,因为只有当用户释放鼠标按钮并且移动完全完成时我才必须执行位置检查(并最终启动动画)。

\n

这是真正的问题:当用户单击标题栏时,似乎无法检测鼠标释放事件(或获取鼠标按钮状态),因为它是由操作系统而不是 Qt 控制的。\nI还尝试使用QWidget::x11event(XEvent* e)\xe2\x80\xa6 但事件仅收集在窗口内,而不是标题栏内。

\n

有人知道如何实现这一目标吗?

\n

我怀疑我必须自己重新实现标题栏\xe2\x80\xa6 太糟糕了\xe2\x80\xa6

\n

小智 6

意识到这是一个非常古老的问题,当您尝试“Qt 检测窗口移动事件的结束”时,这是第一个出现的问题。因此,我想添加一个与当前(截至撰写本文时)Qt 版本 5.12.3 配合良好的解决方案。

您可以设置一个小型状态机,该状态机提供边界以了解何时使用QObject::eventFilter(). QEvent::NonClientAreaMouseButtonPress在 Qt 5.12.x 中,当鼠标在窗口的非客户区域(例如标题栏)下落时,您将收到一个事件QEvent::Move,当窗口位置发生变化(如果有的话)时,您将收到一个后续事件,然后QEvent::NonClientAreaMouseButtonRelease释放鼠标按钮时的最终事件。

了解此序列并使用持久布尔状态标志 ( ) 来了解位置实际发生变化,将在您的方法user_moved_window中提供以下代码片段:QObject::eventFilter()

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    QEvent::Type event_type = event->type();
    [...]
    else if(event_type == QEvent::NonClientAreaMouseButtonPress)
        user_moved_window = false;
    else if(event_type == QEvent::Move && isVisible())
        user_moved_window = true;
    else if(event_type == QEvent::NonClientAreaMouseButtonRelease)
    {
        if(user_moved_window)
        {
            // do what you need to do to here to respond to
            // the end of the reposition event...

            user_moved_window = false;
        }
    }
    [...]
    return MainWindow::eventFilter(obj, event);
}
Run Code Online (Sandbox Code Playgroud)

您可能需要根据您的情况添加一些额外的检查——例如,确保obj事件实际上是主窗口——但这个示例非常适合我使用 Qt 5.12.3 的生产代码。


liu*_*ios 5

我有和你一样的问题。moveEvent 在其移动过程中的每个点都会被触发,并且 Qt 没有提供明确的方法来确定移动的结束。

但现在,受到divanov答案的启发,我发现当我们在移动对话框后释放鼠标时,总会触发类型为173的事件。这就是 QEvent::NonClientAreaMouseMove。

所以代码很简单。

首先安装事件过滤器并声明一个成员变量:int nLastEvent;

bool Win::eventFilter(QObject *obj, QEvent *event)
{
    if (nLastEvent == QEvent::Move && event->type() == 173)
    {
        // do what you wanna do here when the mouse is released,
        // like attaching the dialog to the main window
    }
    nLastEvent = event->type();
    return QWidget::eventFilter(obj, event);
}
Run Code Online (Sandbox Code Playgroud)

足够简单、高效,不是吗!

希望它对您也有用。:)