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'
十分だったでしょう。