ようこそ
前回 、 pyuic4プログラムによって生成されたファイルのロジックに基づいてPyQt4アプリケーションを作成する方法について説明しました。 よくあることですが、このトピックを書いた後は、多くの興味深い、そして最も重要なことには、なぜ私が正しいのか、他の人は間違っているのかを説明する有意義なコメントを受け取りました。
最も興味深いのは、議論がパイオニストとC ++の支持者の両方にとって興味深いことです。なぜなら、この場合、違いは小さく、基本的には構文の重要でないことだけだからです。 これは、PyQt4が本質的にすべての名前とメソッドを保持するC ++ Qtクラスの単純なラッパーであるためです。 それで、ここでお茶やコーヒーを飲んで、自分を快適にして、会話を始めましょう。
すぐに
そのため、ウィンドウアプリケーションを作成しています。 ここで強調しているのは「 ウィンドウ 」という言葉です。これは、ボタンをクリックすることの魅力をエンドユーザーが理解できるユーザーフレンドリーなインターフェースがあることを意味します。 したがって、エラーのデバッグとキャッチにコンソールを使用します。 しかし、すでに美しいウィンドウを持っているユーザーにコンソールを提供するのはなぜですか? ここでは、利便性のために何をするかを選択できます-作業のログを保持します(この方法は、Microsoftが大好きで、ログで最も興味深いものをすべて収集し、アプリケーションの操作に関するレポートを送信するかどうかを尋ねます)またはコンソール出力をフォーム上のウィジェットにリダイレクトして、対処する。 そして、最初のものが非常に簡単に行われた場合:
Copy Source | Copy HTML import sys # sys .stdout = open ( "log.txt" , "a+" ) sys .stderr = open ( "errors.txt" , "a+" )
Copy Source | Copy HTML import sys # sys .stdout = open ( "log.txt" , "a+" ) sys .stderr = open ( "errors.txt" , "a+" )
Copy Source | Copy HTML import sys # sys .stdout = open ( "log.txt" , "a+" ) sys .stderr = open ( "errors.txt" , "a+" )
Copy Source | Copy HTML import sys # sys .stdout = open ( "log.txt" , "a+" ) sys .stderr = open ( "errors.txt" , "a+" )
Copy Source | Copy HTML import sys # sys .stdout = open ( "log.txt" , "a+" ) sys .stderr = open ( "errors.txt" , "a+" )
次に、2番目の質問には多くの質問があります。 実際、この例では手がかりが隠されています。 何がありますか? 最後に行を追加できるファイルのようなオブジェクト。 Pythonでファイルを操作して覚えている限り、これはwrite()メソッドを使用して行われます。 では、 write()メソッドでオブジェクトを作成し 、出力ウィジェットをパラメーターとして渡しましょう!
Copy Source | Copy HTML
- クラス Logger (オブジェクト):
- def __init__ (自己、出力):
- self .output = output
- def write (self、string):
- そうでない場合 (string == "\ n" ):
- trstring = QtGui.QApplication.translate( " MainWindow " 、 string .strip()、None、QtGui.QApplication.UnicodeUTF8)
- self .output.append(trstring)
同時に、多くの場合、ログの半分が空の行で占められないように、行から不要なものをすべて切り取り、改行文字をチェックする必要があります。
次に、コンソール出力をウィジェットにリダイレクトするには、ウィンドウクラスに登録し、ロガークラスを介して標準出力にバインドする必要があります。
Copy Source | Copy HTML
- self .logText = QtGui.QTextEdit(メインウィンドウ)
- #ウィジェットに読み取り専用プロパティを与える
- self .logText.setReadOnly(True)
- #私の意見では、垂直スクロールバーを常に表示する方が便利です
- self .logText.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
- #開始メッセージ
- self .logText.append( "ログ開始" )
- #すべてを1つのウィジェットにリダイレクトするか、エラーを分割して、
- #標準出力
- self .logger = Logger( self .logText)
- self .errors = Logger( self .logText)
- sys .stdout = self .logger
- sys .stderr = self .errors
これで、 self.logger.write()を使用して(ウィンドウクラスで) 、または単にprintを使用して、2つの方法でログに書き込むことができます 。 したがって、 try-exceptで美しいエラー結論を出したので、ウィンドウ内にすべてが表示されます。 ここでさらに大きなプラスは、PythonロジックとQtロジックの分離です。フォームは別のスレッドでハングし、外部関数でエラーが発生してもアプリケーションは終了しませんが、エラーはすぐにログに記録されます。 はい、これについてもう少し詳しく説明する価値があります。
スレッドについて少し
実行に多くの時間とリソースを必要とする関数を登録すると、フォームが「フリーズ」し、関数の状態に関するデータを受け取らないことに、何度も気づいたと思います。 関数から返された値をフォームのリストに順番に出力したいときに、私自身もこれに遭遇しました。 解決策は明らかです-スレッドを使用します。 そして、Pythonロジックでスレッドを使用するか、Qtスレッドを使用するかを選択する必要がありますか? 個人的には、この場合、私は2番目を好む-いくつかの面でトラブルが少ない。
私たちが美しくなるためには、Qtから継承した別のクラスを再度作成する必要があります。 そして、何をすべきか、そのような「クラスロジック」:)長所と短所がありますが、これは今ではありません。
Copy Source | Copy HTML
- クラス myQThread (QtCore.QThread):
- def __init__ (自己、出力):
- QtCore.QThread。 __init__ (自己)
- self .output = output
- def run (self):
- some_big_function_with_output()
ご覧のとおり、最初にQt番目のストリームクラスを初期化します(コンストラクターパラメーターに出力オブジェクトも追加しました-これはフォーム上のまったく同じウィジェットかもしれません)。 次に、標準のrun()メソッドを再定義します。このメソッドには、ストリームが行うべきことを正確に含めます。 この機能は、外部モジュールからでも接続できます-この場合、機能しません。 この場合、その出力は、同じappend()メソッドを使用して渡された出力関数を介して実行できます 。 より美しくするために、プログレスバーまたは他のビジュアライザーを追加して、ストリームが機能していることをユーザーに見えるようにすることができます。
そして、スレッドが作業を完了したことをどのようにして知ることができますか? これを行うには、小さなハックを1つ接続します。ストリームからシグナルプロセッサ用のスロットを作成しますが、 connectを使用せず、decoratorを使用します。
Copy Source | Copy HTML
- @ QtCore.pyqtSignature( "")
- def threadFinished (self):
- self .logger.write( "ストリームは終了しました!" )
はい、はい、あなたは正しく理解しました、これはフォームクラスに書き込まれ、 threadFinished()シグナルが生成されると、プログラムはそれについて教えてくれます。 これらはパイです。
実際には、ストリーム、スロット、および信号の処理をより詳細に検討できますが、最初はこれで十分です。 コミュニケーションの前に、私たちの小さなお茶会を楽しんだことを願っています! コメントを書く:)