【发布时间】:2018-10-02 14:17:15
【问题描述】:
我正在尝试让标准输出和错误消息显示在我的主窗口上。该窗口由 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 编辑器上显示自己。
我相信这与类实例化有关。
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_())
"""
【问题讨论】:
-
我添加了似乎相关的内容。 (代码几千行)
-
什么是
Ui_MyForm?你明白什么是可验证的吗?您的项目可以有数百万行,我们对您的项目不感兴趣,我们对具体问题感兴趣。为此,我们必须能够复制它。 -
它有超过 500 行,所有关于 gui 对象..
-
在你的项目中显示该代码,错误可能是UI设计引起的,需要时间并提供可重现的代码。