【发布时间】:2021-06-24 22:44:50
【问题描述】:
[为清楚起见重新提出问题]
我有一个带有 2 个选项卡的简单 GUI,第一个包含用于程序日志的只读 QTextEdit,第二个包含用于用户输入的各种小部件和一个“生成”按钮。
图形用户界面是使用 Qt 设计器制作的。注意:除了只读的 QTextEdit
之外,所有元素都有默认属性(它们没有被编辑/没有更改选项)
箭头显示用于日志的 QTextEdit 和导致选项卡更改的生成按钮
单击生成按钮后,焦点选项卡将切换到第一个(带有日志),并且使用单独的线程来计算用户数据并将其日志写入 QTextEdit
class GUI:
def __init__(self, core):
self.core = core
self.app = QtWidgets.QApplication(sys.argv)
self.window = Application()
self.__link_buttons__()
def __link_buttons__(self):
generate_button = self.window.get_generate_button()
if generate_button is None:
raise RuntimeError("could not find the generation button needed for the gui ( possibly an issue with the .gui file ), cannot start software")
generate_button.clicked.connect(self.__generate_threaded)
def __generate_threaded(self):
logger.logger_instance.log("user requested generation", LogLevel.NORMAL)
self.window.set_main_tab_to_log()
if self.core.check_if_generating() is True:
logger.logger_instance.log("Generator is currently in use", LogLevel.ERROR)
return
thread = threading.Thread(target=self.core.generate_gui)
thread.start()
class Application(QtWidgets.QMainWindow):
def __init__(self):
super(Application, self).__init__()
self.ui = uic.loadUi(settings.settings_instance.gui_path / "main_window.ui", self)
self.show()
self.__tabs = self.ui.findChild(QTabWidget, "mainTabs")
self.__log_tab = self.ui.findChild(QWidget, "logTab")
def get_gui_handle(self):
return self.ui.findChild(QTextEdit, "LogOutput")
def get_generate_button(self):
return self.ui.findChild(QPushButton, "generateButton")
def set_main_tab_to_log(self):
self.__tabs.setCurrentWidget(self.__log_tab)
记录器是GUI上负责写入QTextEdit的类,它在开始时调用get_gui_handle()方法获取QTextEdit然后使用append()写入它(有线程保护)
可能的重要细节:我使用的是标准 Python 线程 (import threading),而不是 Qt,因为其他软件都使用它们,我不确定它们是否可以混合使用
记录器确实成功写入 QTextEdit,但应用程序未按预期显示文本。任何新文本都会正常显示,但以前的日志不会,并且只会在窗口调整大小/单击文本/更改选项卡/...时显示(我认为是让应用程序重新呈现 QTextEdit 的事件)
图片清晰:
第一个日志按预期显示:
第二个日志也按预期显示,但第一个日志现在不可见
在窗口调整大小/文本覆盖/选项卡更改后再次显示第一个日志
【问题讨论】:
-
除了上述关于 MRE 的建议之外,我要求您考虑这一点:您向我们提供了详细信息,但它们不是实际详细信息。例如:“我用于记录的 QTextEdit”:记录 what? 如何完成的? “输出是生成的”:生成如何?从什么?根据您要解释的内容,第一个想法是您可能正在尝试以某种方式使用线程(这 not 允许直接访问 UI 元素,因此存在更新问题 - 而您'很幸运,因为这通常会导致致命的崩溃),但在您的详细信息变为实际详细信息之前,我们无法确定。
-
对不起,我会编辑问题,确实不够清楚
-
添加了很多上下文和代码,谢谢指导^^
-
现在好多了,但还是不够。正如所怀疑的那样,您正在使用线程,这肯定是问题的根源(用户界面应该始终在主线程中,并且绝对应该没有直接访问试图从外部线程获取 UI 元素),但我们无法提供更多信息,除非您提供 完整 minimal reproducible example:您的代码缺少 非常 重要部分,例如 @987654334 @ 以及实际尝试更新文本的内容;请注意,我们应该能够复制、粘贴和运行您的代码,而无需进行任何实质性修改。
-
感谢您的回答。由于代码非常大,这有点难做,我认为如果我从头开始创建一个小示例而不是尝试提取重要部分(代码长达数千行)会更简单。 UI 从主线程运行,任何繁重的计算都在单独的线程上完成。您似乎对线程有所怀疑,我应该如何处理从单独线程到 QTextEdit 的写入?有没有我可以使用的事件/方法?
标签: python-3.x pyqt5