在拖动/调整窗口大小时调用窗口上的isActive()时,false返回.(X11,Qt 5.4.0)

BOO*_*tak 5 c++ linux x11 qt pyqt

我在Linux(X11)上使用Qt 5.4.0,我需要确定,如果我的窗口是活动的.所以,我编写了示例代码,如下所示.如果该代码在Windows上编译,则仅当窗口未真正激活时,它才会在控制台中记录"false".但是在linux(X11)上,当我开始拖动或调整窗口大小时,它也会记录"false".为什么会发生这种情况以及如何解决这个问题?我想知道,当我的窗口真的处于非活动状态时,它处于活动状态,但被拖动/调整大小.

code snippet(C++):

void MainWindow::changeEvent(QEvent *e) {
    if (e->type() == QEvent::ActivationChange) {
        if (this->isActiveWindow()) {
            std::cout << "True" << std::endl;
        } else {
            std::cout << "False" << std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

PyQt5上的相同代码:

import sys
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import QWidget, QApplication


class TransparentWidget(QWidget):
    def __init__(self):
        super(TransparentWidget, self).__init__()

    def changeEvent(self, e):
        if e.type() == QEvent.ActivationChange:
            print(self.isActiveWindow())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    transparent_widget = TransparentWidget()
    transparent_widget.show()
    app.exec_()
Run Code Online (Sandbox Code Playgroud)

JvO*_*JvO 1

它可能注册为“false”,因为在 X 上您看到的窗口实际上是两个窗口:您在其中绘制内容的窗口和一个稍大的窗口,后者是您的父窗口并包含边框。

原因是 X11 没有“装饰边框”的概念,包括关闭/最大/最小按钮、标题栏、漂亮的渐变颜色、圆形边框等(原生 X11 窗口可以有边框,但只能是纯色)或纹理)。这些控件由您的窗口管理器提供。发生的情况是,如果您创建一个窗口,窗口管理器会创建一个额外的 X11 窗口,该窗口比您的窗口稍大,并将您的窗口作为子窗口放置在这个新窗口上。从那时起,这两个窗口就紧密相连:调整窗口大小将调整父窗口的大小,反之亦然。

这一切都由窗口管理器处理。例如,如果您想调整窗口大小并单击边框,则单击不会到达您的窗口,而是到达窗口管理器,然后窗口管理器确定单击的位置并决定如何处理它。所以此时你自己的窗口不再处于活动状态,这解释了为什么 isActiveWindow() 返回 false。

对于 Microsoft Windows,边框是窗口本身不可分割的一部分,因此这就是它保持“活动”状态的原因。

无论如何,要确定您的窗口是否处于“活动”状态,您应该使用 QFocusEvent。通过查看gotFocus()和lostFocus()值,您应该能够跟踪窗口何时处于活动状态。