gpt4 book ai didi

python - pyqt5 QApplication.topLevelWidgets 问题

转载 作者:行者123 更新时间:2023-12-04 15:36:56 25 4
gpt4 key购买 nike

“Qthread_check.py”的目的是查找 MS Office 文件。

并将结果传递给“main_gui.py”所以我必须找到“main_gui.FindExcel”

我用了QApplication.topLevelWidgets找到“main_gui.FindExcel”

然而,TopLevelWidgetsisinstance结果和我想的不一样。

  • python 3.7
  • pyqt 5.12.2

main_gui.py

[... pyqt5 import...]
import sys
import os
import check_core
import Qthread_check

class FindExcel(QWidget):
def __init__(self):
super().__init__()
self.label_width = 90
self.core = check_core.CheckCore()
self.th = Qthread_check.Search()
self.run_pw = Qthread_check.SetPW()
self.initro_msg = "hihi"
self.init_gui()

def init_gui(self):
# intro msg
intro_label = QLabel()
intro_label.setText(self.initro_msg)

[... Widget And layout ...]

class MainWin(QMainWindow):
def __init__(self):
super().__init__()
self.main_ui_layout()

def main_ui_layout(self):
# create QTabWidget and add Tab..
tab_w = QTabWidget()
tab_w.addTab(GeneralCheck(), "General Check")
tab_w.addTab(FindExcel(), "MS Office PW")

self.setWindowTitle("T.T")

# Set main Central Widget
self.setCentralWidget(tab_w)
self.setGeometry(100, 100, 900, 900)
self.show()

if __name__ == "__main__":
app = QApplication(sys.argv)
start = MainWin()
sys.exit(app.exec_())

Qthread_check.py

from PyQt5.QtCore import QThread, pyqtSignal, QWaitCondition, QMutex
from PyQt5.QtWidgets import QApplication
import Main_gui

class Search(QThread):
file_changed = pyqtSignal(str)
done_msg = pyqtSignal(dict)

def __init__(self):
QThread.__init__(self)
self.cond = QWaitCondition()
self.mutex = QMutex()
self._status = False
for w in QApplication.topLevelWidgets():
print(w, isinstance(w, Main_gui.FindExcel)) #<<=== Why is this no match?
print("")

self.main_gui = [w for w in QApplication.topLevelWidgets() if isinstance(w, Main_gui.FindExcel)][0] #<== self.main_gui = []
def __del__(self):
self.wait()

def run(self):
[...]

为什么我会得到以下结果?我不知道为什么 self.main_gui是空的。

我认为这是真的。 ==> <__main__.FindExcel object at 0x031FFC60> False

但是..

# for w in QApplication.topLevelWidgets():
# print(w, isinstance(w, Main_gui.FindExcel))
# print("")

# result from above

<__main__.FindExcel object at 0x031FFC60> False <==== why?
<PyQt5.QtWidgets.QTabWidget object at 0x031FF990> False
<__main__.MainWin object at 0x031FF7B0> False
<PyQt5.QtWidgets.QMenu object at 0x031FF8F0> False
<PyQt5.QtWidgets.QMenu object at 0x031FF940> False

Process finished with exit code 1

请帮忙...

    def __init__(self):
QThread.__init__(self)
self.cond = QWaitCondition()
self.mutex = QMutex()
self._status = False
for w in QApplication.topLevelWidgets():
print(w, w.__class__, Main_gui.FindExcel, isinstance(w, Main_gui.FindExcel))
print("")

输出

<PyQt5.QtWidgets.QMenu object at 0x0383F940> <class 'PyQt5.QtWidgets.QMenu'> <class 'Main_gui.FindExcel'> False
<PyQt5.QtWidgets.QTabWidget object at 0x0383F990> <class 'PyQt5.QtWidgets.QTabWidget'> <class 'Main_gui.FindExcel'> False
<PyQt5.QtWidgets.QMenu object at 0x0383F8F0> <class 'PyQt5.QtWidgets.QMenu'> <class 'Main_gui.FindExcel'> False
<__main__.FindExcel object at 0x0383FC60> <class '__main__.FindExcel'> <class 'Main_gui.FindExcel'> False
<__main__.MainWin object at 0x0383F7B0> <class '__main__.MainWin'> <class 'Main_gui.FindExcel'> False

最佳答案

说明:

正如您在执行时指出的那样:

print(w, w.__class__, Main_gui.FindExcel, isinstance(w, Main_gui.FindExcel))

输出是:

# ...
<__main__.FindExcel object at 0x0383FC60> <class '__main__.FindExcel'> <class 'Main_gui.FindExcel'> False
# ...

据观察,对象的 __class__ 是 __main__.FindExcel,这与我怀疑产生问题的 Main_gui.FindExcel 不同。

isinstance() 似乎没有考虑类和实例创建在不同作用域的情况。另外,可能是 PyQt5 错误。

解决方案:

解决方案一:

尽管我认为不需要使用 topLevelWidgets(),因为您可以直接传递 FindExcel:

# ...
class FindExcel(QWidget):
def __init__(self):
super().__init__()
self.label_width = 90
self.core = check_core.CheckCore()
self.th = Qthread_check.Search(<b>self</b>)
# ...
# ...
class Search(QThread):
file_changed = pyqtSignal(str)
done_msg = pyqtSignal(dict)

def __init__(self, <b>main_gui</b>):
QThread.__init__(self)
self.cond = QWaitCondition()
self.mutex = QMutex()
self._status = False
<b>self.main_gui = main_gui</b>
# ...

解决方案 2:

另一种选择是通过将 if __name__ == "__main__": 代码移动到另一个文件来重构您的项目:

|-- another_file.py
|-- Main_gui.py
`-- Qthread_check.py

另一个文件.py

from PyQt5.QtWidgets import QApplication

from Main_gui import MainWin


if __name__ == "__main__":
app = QApplication(sys.argv)
start = MainWin()
sys.exit(app.exec_())

解决方案 3:

或者如果你仍然想使用 topLevelWidgets() 那么你可以使用 QMetaObject 来获取类名,然后用它来过滤它:

# ...
class Search(QThread):
file_changed = pyqtSignal(str)
done_msg = pyqtSignal(dict)

def __init__(self):
QThread.__init__(self)
self.cond = QWaitCondition()
self.mutex = QMutex()
self._status = False
<b>self.main_gui = None
for w in QtWidgets.QApplication.topLevelWidgets():
if w.metaObject().className() == "FindExcel":
self.main_gui = w
break
print(self.main_gui)</b>
# ...

注意:FindExcel仅在构造时是一个topLevelWidget,因为那时它是QTabWidget的一部分,因此它不再是一个窗口。

关于python - pyqt5 QApplication.topLevelWidgets 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59418970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com