Windows 上的 Qt 5.4.0,在某些情况下 returns 上调用 QWidget 的 isActive() 显然是错误的值
Qt 5.4.0 on Windows, isActive() called on QWidget in some cases returns obviously wrong value
在某些情况下,在 Windows 平台上,isActive() 在 QWidget 上调用 returns true,显然,它不能激活。
例如,我的应用程序在 GUI 线程上做了很多工作,并在启动后显示 window 有一些延迟。如果我启动应用程序并在应用程序显示 main window 之前切换到另一个应用程序,当显示 window 时,它肯定会处于非活动状态。但是在这种情况下调用 isActive() returns true。如果我切换到我的应用程序并切换回另一个应用程序,isActive() 将像往常一样为 false。但一开始它是真的,这不是通常应该是的。顺便说一下,在 linux 和 OS X 上它按计划工作。
我该如何解决?或者我该如何解决?
重现该问题的示例代码如下。这是 PyQt,但相信我,Qt 也重现了这个问题。
import sys
from time import sleep
from PyQt5.QtWidgets import QWidget, QApplication
class BadWidget(QWidget):
def __init__(self):
super(BadWidget, self).__init__()
self.startTimer(500)
def timerEvent(self, e):
print(self.isActiveWindow() and not self.isMinimized())
if __name__ == '__main__':
app = QApplication(sys.argv)
bad_widget = BadWidget()
sleep(1)
bad_widget.show()
app.exec_()
错误的解决方案:在请求小部件状态之前调用 QApplication::processEvents()
。
好的解决方案:通过QtConcurrent或其他多线程方式在线程池中"much work"
你可以试试isVisible() && isActiveWindow() && !isMinimized()
最后,我找到了一些完全符合我要求的可行解决方案。不幸的是,它只能使用 WinAPI 调用来完成,但没关系。
大意是在Windows上,"active"和"foreground"window不是一回事。更多信息在这里:
最终解决方案如下所示:
if sys.platform.startswith('win'):
if ctypes.c_long(self.effectiveWinId()).value ==\
windll.user32.GetForegroundWindow():
# active
else:
# inactive
else:
if self.isActiveWindow():
# active
else:
# inactive
在某些情况下,在 Windows 平台上,isActive() 在 QWidget 上调用 returns true,显然,它不能激活。
例如,我的应用程序在 GUI 线程上做了很多工作,并在启动后显示 window 有一些延迟。如果我启动应用程序并在应用程序显示 main window 之前切换到另一个应用程序,当显示 window 时,它肯定会处于非活动状态。但是在这种情况下调用 isActive() returns true。如果我切换到我的应用程序并切换回另一个应用程序,isActive() 将像往常一样为 false。但一开始它是真的,这不是通常应该是的。顺便说一下,在 linux 和 OS X 上它按计划工作。
我该如何解决?或者我该如何解决?
重现该问题的示例代码如下。这是 PyQt,但相信我,Qt 也重现了这个问题。
import sys
from time import sleep
from PyQt5.QtWidgets import QWidget, QApplication
class BadWidget(QWidget):
def __init__(self):
super(BadWidget, self).__init__()
self.startTimer(500)
def timerEvent(self, e):
print(self.isActiveWindow() and not self.isMinimized())
if __name__ == '__main__':
app = QApplication(sys.argv)
bad_widget = BadWidget()
sleep(1)
bad_widget.show()
app.exec_()
错误的解决方案:在请求小部件状态之前调用 QApplication::processEvents()
。
好的解决方案:通过QtConcurrent或其他多线程方式在线程池中"much work"
你可以试试isVisible() && isActiveWindow() && !isMinimized()
最后,我找到了一些完全符合我要求的可行解决方案。不幸的是,它只能使用 WinAPI 调用来完成,但没关系。
大意是在Windows上,"active"和"foreground"window不是一回事。更多信息在这里:
最终解决方案如下所示:
if sys.platform.startswith('win'):
if ctypes.c_long(self.effectiveWinId()).value ==\
windll.user32.GetForegroundWindow():
# active
else:
# inactive
else:
if self.isActiveWindow():
# active
else:
# inactive