一旦另一个窗口打开,Stdout就会停止在QTextEdit中显示

时间:2018-04-22 12:13:47

标签: python pyqt pyqt5 stdout

我正在尝试在我的主窗口上显示stdout和错误消息。窗口由pyqt制作,由设计师制作。我有一个QTextEdit。这是输出应该显示的位置。此外,我有一个对话框(再次通过设计师制作),我在运行它之前为我的程序设置了一些设置。对话框打开如下:

def open_settings(self):
    dialog = SettingsDialog()
    dialog.open_settings_tab()  # its on a tab widget

我已阅读并使用这些链接上的信息来实现我的目标:

Print out python console output to Qtextedit

How to capture output of Python's interpreter and show in a Text widget?

两者对于不同的对象名称几乎相同。我遇到的问题是每当我打开一个对话框并返回主窗口时,stdout就不再显示在QTextEdit上。相反,它会回到Sublime Editor上展示自己。

我认为这与班级实例有关。

以下是Dialog类的启动方式:

class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super(SettingsDialog, self).__init__(parent)
        self.ui = Ui_SettingsDialog()
        self.ui.setupUi(self)

最后这是我的主窗口(窗体)类的开始:

class MyForm(QMainWindow):
    def __init__(self, parent=None):
        super(MyForm, self).__init__(parent)

        # Install the custom output stream
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)

        self.ui = Ui_MyForm()
        self.ui.setupUi(self)

当我进入对话框屏幕然后回来时,为什么stdout停止工作(在qtextedit中)的任何想法?

新更新: 代码很长。我制作了一个显示问题的小程序:

PS:我发现问题与下面这一行有关:

self.ui.pushButton_path.clicked.connect(Form(self).change_path)

如果我发表评论,问题就会消失..但我需要调用该函数(从主窗体中打开一个QDialog)。什么是正确的方法?

主:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtGui import QTextCursor

from ui_form import Ui_Form
from ui_dialog import Ui_Dialog


class EmittingStream(QObject):  # test
    textWritten = pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))


class Form(QMainWindow):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        # Install the custom output stream
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)  # test

        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.ui.pushButton_open.clicked.connect(self.open_dialog)
        self.ui.pushButton_text.clicked.connect(self.test_write)

    def __del__(self):  # test
        # Restore sys.stdout
        sys.stdout = sys.__stdout__

    def normalOutputWritten(self, text):  # test
        """Append text to the QTextEdit."""
        # Maybe QTextEdit.append() works as well, but this is how I do it:
        # self.ui.tEdit_cli.insertPlainText(text)
        cursor = self.ui.textEdit.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.ui.textEdit.setTextCursor(cursor)
        self.ui.textEdit.ensureCursorVisible()

    def open_dialog(self):
        dialog = Dialog()
        dialog.open_tab()

    def test_write(self):
        print("something written")

    def change_path(self):
        pass


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        self.ui.pushButton_close.clicked.connect(self.close_dialog)

        self.ui.pushButton_path.clicked.connect(Form(self).change_path)  # this is what causes the issue. but i need to use it!

    def open_tab(self):
        self.ui.tabWidget.setCurrentIndex(0)
        self.exec_()

    def close_dialog(self):
        self.close()


def main():
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

ui_dialog:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'dialog.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.horizontalLayout = QtWidgets.QHBoxLayout(Dialog)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.tabWidget = QtWidgets.QTabWidget(Dialog)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.pushButton_close = QtWidgets.QPushButton(self.tab)
        self.pushButton_close.setGeometry(QtCore.QRect(100, 80, 211, 131))
        self.pushButton_close.setObjectName("pushButton_close")
        self.pushButton_path = QtWidgets.QPushButton(self.tab)
        self.pushButton_path.setGeometry(QtCore.QRect(30, 30, 75, 23))
        self.pushButton_path.setObjectName("pushButton_path")
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.horizontalLayout.addWidget(self.tabWidget)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton_close.setText(_translate("Dialog", "close"))
        self.pushButton_path.setText(_translate("Dialog", "path"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Dialog", "Tab 1"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Dialog", "Tab 2"))


"""
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())
"""

ui_form:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'form.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(Form)
        self.centralwidget.setObjectName("centralwidget")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(90, 230, 601, 271))
        self.textEdit.setObjectName("textEdit")
        self.pushButton_open = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_open.setGeometry(QtCore.QRect(140, 80, 241, 81))
        self.pushButton_open.setObjectName("pushButton_open")
        self.pushButton_text = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_text.setGeometry(QtCore.QRect(440, 80, 251, 81))
        self.pushButton_text.setObjectName("pushButton_text")
        Form.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(Form)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        Form.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(Form)
        self.statusbar.setObjectName("statusbar")
        Form.setStatusBar(self.statusbar)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "MainWindow"))
        self.pushButton_open.setText(_translate("Form", "open dialog"))
        self.pushButton_text.setText(_translate("Form", "write somthing"))


"""
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QMainWindow()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())
"""

1 个答案:

答案 0 :(得分:1)

您必须使用该对象来调用方法,您不能使用该类,因此指令Form(self)无效。

您必须在可以同时访问信号和插槽的位置建立连接,例如open_dialog将是一个好地方:

class Form(QMainWindow):
    ...
    def open_dialog(self):
        dialog = Dialog(self)
        dialog.ui.pushButton_path.clicked.connect(self.change_path) # +++
        dialog.open_tab()

    def test_write(self):
        print("something written")

    def change_path(self):
        pass


class Dialog(QDialog):
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.pushButton_close.clicked.connect(self.close_dialog)
        # self.ui.pushButton_path.clicked.connect(Form(self).change_path) ---
    ...