MainWindow закрывается после инициализации
Я хотел начать новый проект, используя PyQt5 и QtDesigner. Для начала я просто скопировал код из предыдущих проектов в PyQt4 и настроил его на изменения в PyQt5. Итак, код для запуска Main Window
и Timer
который обновляет приложение, выглядит так:
# ====Python=============================================================
# SticksNStones
# =======================================================================
import ...
FPS = 45
dt = 1000.0 / FPS
class SNSMainWindow(WindowBaseClass, Ui_Window):
def __init__(self, parent=None):
WindowBaseClass.__init__(self, parent)
Ui_Window.__init__(self)
self.setupUi(self)
self.paused = False
self.timer = None
self.init()
def init(self):
# Setup Display
self.display.setup()
# Setup timer
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.update_loop)
self.timer.start(self.dt)
def update_loop(self):
if not self.paused:
self.display.update(dt)
else:
pass
# ==================================
# Start Application
# ==================================
_dialog = None
def start_sns():
global _dialog
# Start App and frame
app = QtWidgets.QApplication(sys.argv)
_dialog = SNSMainWindow()
_dialog.show()
# Exit if window is closed
sys.exit(app.exec_())
if __name__ == "__main__":
start_sns()
Но как только я запускаю приложение, оно закрывается после инициализации. Отладка показала, что таймер активен, но update_loop
никогда не называется.
Код PyQt4, из которого я скопировал, прекрасно работает, и я просто не могу понять, почему это не работает, так как все примеры, которые я нашел в Интернете, имеют одинаковый код.
Вопрос в том, почему приложение закрывается при запуске?
Обновить
Проблема не в таймере, а в использовании кастомного.ui. Если я запускаю код с
class SNSMainWindow(QtWidgets.QFrame):
def __init__(self, parent=None):
QtWidgets.QFrame.__init__(self, parent)
...
окно открывается, и оно остается открытым, пока я не закрою его. Но босой
ui_path = os.path.dirname(os.path.abspath(__file__)) + "/ui/sns_main.ui"
Ui_Window, WindowBaseClass = uic.loadUiType(ui_path)
class SNSMainWindow(WindowBaseClass, Ui_Window):
def __init__(self, parent=None):
WindowBaseClass.__init__(self, parent)
Ui_Window.__init__(self)
self.setupUi(self)
# ==================================
if __name__ == "__main__":
# Start App and frame
app = QtWidgets.QApplication(sys.argv)
_dialog = SNSMainWindow()
_dialog.show()
# Exit if window is closed
sys.exit(app.exec_())
просто исчезает в течение миллисекунд после показа. С другой стороны, использование собственного виджета в PyQt4 также остается открытым. Я добавил uic.load
часть, которая работает просто отлично. Я что-то упускаю при конвертации в PyQt5?
Решение
Я нашел решение проблемы в своем пользовательском классе отображения. В случае paintEvent
дисплей будет пытаться получить (пока) неопределенное свойство. Но вместо того, чтобы вызвать исключение, что свойство не было определено, окно просто закрылось.
Определение свойства при инициализации виджета решило проблему. Это просто заставляет меня задуматься, почему в этом случае не возникают исключения, поскольку виджет явно пытается вызвать некоторые неопределенные свойства. Просто
AttributeError: 'NoneType' object has no attribute 'xxx'
было бы достаточно.
1 ответ
Я бы попробовал изменить некоторые строки, сначала попробую изменить app
определение к
app = QtGui.QApplication(sys.argv)
Затем удалите Ui_Window
инициализировать и установить его self.ui = Ui_Window()
class SNSMainWindow(WindowBaseClass):
def __init__(self, parent=None):
WindowBaseClass.__init__(self, parent)
self.ui = Ui_Window()
self.ui.setupUi(self)
self.paused = False
self.timer = None
self.init()