2016-10-15 4 views
0

コンソールとQTextBrowserウィジェットの両方にstdoutを送信しようとしています。しかし、私は無限ループのいくつかの種類を取得しているし、アプリケーション終了します。ここでstdoutをリダイレクトしようとすると無限ループが発生する

は私のコードです:

import sys 
from PyQt5 import QtWidgets, uic 
from PyQt5.QtCore import * 

qtCreatorFile = "qt_ui.ui" 
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile) 

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): 
    def __init__(self): 
     QtWidgets.QMainWindow.__init__(self) 
     Ui_MainWindow.__init__(self) 
     self.setupUi(self) 
     self.start_button.clicked.connect(printing) 

def printing(): 
    print("Pressed!\n") 

class Logger(QObject): 
    def __init__(self): 
     super().__init__() 
     self.terminal = sys.stdout 

    def write(self, message): 
     self.terminal.write(message) 
     self.log_browser.setText(message) #problem is in this line 

    def flush(self): 
     pass 

if __name__ == "__main__": 
    sys.stdout = Logger() 
    app = QtWidgets.QApplication(sys.argv) 
    window = MainWindow() 
    window.show() 
    sys.exit(app.exec_()) 

その結果、ときクリックSTART_BUTTON、以下が観察される:

"C:\...\python.exe" "E:/.../qt_gui.py" 
Pressed! 
Pressed! 
Pressed! 
... (totaly 332 times) 
Pressed! 
Pressed! 
Pressed! 

Process finished with exit code 1 

この行はループを作る、なぜ私は理解できません

self.log_browser.setText(message) 

1番目の回答後に編集:

上記の行をprint(message)に置き換えましたが、同じ結果が得られました。助けていただければ幸いです。

+0

クラスdefintion –

+0

下にインデントエラーはそれがない元のコードから、コピー/貼り付けエラーだっあります。私はそれを修正しました。 – dandepeched

答えて

0

あなたはLoggerからカスタム信号を発すると、ログブラウザに接続できます。

class Logger(QObject): 
    loggerMessage = pyqtSignal(str) 

    def __init__(self): 
     super().__init__() 
     self.terminal = sys.stdout 

    def write(self, message): 
     self.terminal.write(message) 
     self.loggerMessage.emit(message) 

    def flush(self): 
     pass 

if __name__ == "__main__": 

    sys.stdout = Logger() 
    app = QtWidgets.QApplication(sys.argv) 
    window = MainWindow() 
    sys.stdout.loggerMessage.connect(window.log_browser.insertPlainText) 
    window.show() 
    sys.exit(app.exec_()) 
+0

このコードを試しましたが、メッセージはQTextBrowserに表示されません。どんな提案? – dandepeched

+0

@dandepeched。 'print'が' stdout' *を2回書く - 一度はテキスト、もう一度endlineを書くようです。したがって 'setText'を使うと、2番目のシグナルが最初のシグナルを上書きします。私は 'insertPlainText'を使うように私の例を変更したので、代わりにすべてのメッセージを追加します。 – ekhumoro

+0

これは働いた!どうもありがとう! – dandepeched

0

あなたが投稿したコードは、実行したコードではないようですが、それが代表であると仮定すると、2つのエラーがあります:Loggerの基本クラスをインクルードしなければならず、self.log_browserはどこにも定義されていません。しかし、これはループ、アプリの終了を引き起こさない(例外があるが例外フックはないので、参照)。私はlog_browserをどのようにすべきか分からないので、私はそれを何かを受け入れるMock()(unittest.mockから)として定義し、問題は消え去る。

class Logger(QObject): 
    def __init__(self): 
     super().__init__() 
     self.terminal = sys.stdout 
     from unittest.mock import Mock 
     self.log_browser = Mock() 

    def write(self, message): 
     self.terminal.write(message) 
     self.log_browser.setText(message) # problem was this line 

    def flush(self): 
     pass 
+0

log_browserは、 "qt_ui.ui"ファイルで定義されています。 – dandepeched

+0

self.log_browser = QtWidgets.QTextBrowser(self.centralwidget) – dandepeched

+0

log_browserをprint関数に置き換えてコードを単純化しました。あなたが言ったように初期化されたクラスも同じ動作をします。 – dandepeched

関連する問題