Объяснение:
Чтобы понять проблему, необходимо проанализировать следующие 2 кода и их выходные данные:
Example1
from PyQt5 import QtCore
if __name__ == "__main__":
app = QtCore.QCoreApplication([])
o = QtCore.QObject()
o.destroyed.connect(lambda: print("destroyed o"))
o = QtCore.QObject()
def on_timeout():
print("quit")
QtCore.QCoreApplication.quit()
QtCore.QTimer.singleShot(1000, on_timeout)
app.exec_()
destroyed o
quit
Example2
from PyQt5 import QtCore
if __name__ == "__main__":
app = QtCore.QCoreApplication([])
o = QtCore.QObject()
o.destroyed.connect(lambda: print("destroyed o"))
p = o
o = QtCore.QObject()
def on_timeout():
print("quit")
QtCore.QCoreApplication.quit()
QtCore.QTimer.singleShot(1000, on_timeout)
app.exec_()
quit
destroyed o
В первом примере переменной "o" назначается объект QObject, а когда назначается другой объект QObject, исходный объект QObject удаляется, поэтому " destroy "печатается перед" quit ".
Во втором примере он имеет разницу" p = o ", когда делается ссылка на QObject, то есть в этой строке" p "и" o " представляют один и тот же объект, поэтому, присваивая "или" новый QObject, исходный QObject не уничтожается, а уничтожается только тогда, когда заканчивается l oop и G C выполняет свою работу.
Это то, что происходит в вашем случае тонким способом, логика c из "p = o" заключается в том, что объект QObject хранится в другом "месте", а в вашем примере это "место" - это лямбда, которая имеет свою собственную сфера (аналогично с частичной). В частности, в вашем примере было создано новое окно, разрушающее предыдущее, в результате чего все время отображается одно окно.
Решение:
Одним из возможных решений является предотвращение первого окна от удаления и создания нового окна с использованием флага:
from PyQt5 import QtCore, QtGui, QtWidgets
<b>flag = False</b>
# ...
def open_otherwindow():
<b>global w, flag
if not flag:
w = OtherWindow()
w.show()
flag = True</b>
# ...