3

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'

十分だったでしょう。

4

1 に答える 1