【Qt】控制台信息输出到GUI中(在TensorFlow、PySide6环境下,将训练信息实时输出在文本框中)

1.前言

本文主要是介绍如何将控制台的内容实时的输出到GUI中。

主要实现方式就是通过多线程,一个GUI的线程,还有一个线程提供给想要输出的程序。

需要两个线程的原因是,GUI主线程一旦启动,直到下一次调用刷新页面功能的操作出现之前,都无法改变当前界面,因此需要另外一个线程来改变GUI的内容。

2.实现

实现功能为:将训练模型的信息,输出到GUI中的文本框中,假设文本框为 W

思想如下:

  1. 在GUI中,定义一个如何更新 W 中内容的函数 onUpdateText()
  2. 自定义一个输出流 Stream ,将某个地方的输出重定向到另一个地方
  3. 在GUI中,将 onUpdateText() 函数 绑定到 输出流 Stream 中的 newText 中,表示新的输出点为 onUpdateText() 函数所操作的对象
  4. 将sys的stdout设置为自定义的输出流 Stream,即将控制台的输出重定向到 Stream 中定义的新位置
  5. 编写另一个线程,将功能函数(即训练函数)写在线程的run中
  6. 在GUI中调用线程,执行功能函数,功能函数原本输出在控制台的信息,就被重定向到W
  7. 在关闭GUI的时候,将sys的stdout重置为 sys.__stdout__

3.代码

本次实验中使用的GUI库为PySide6,训练代码基于TensorFlow编写

import ctypes
import sys
from PySide6.QtCore import QObject, Signal, QThread
from PySide6.QtWidgets import QMainWindow, QPushButton, QApplication, QTextEdit
from PySide6.QtGui import QTextCursor
from test_code.tmp_train_saxs import train_saxs
import win32con


# 自定义的输出流,将输出重定向到某个地方
class Stream(QObject):
    """Redirects console output to text widget."""
    newText = Signal(str)

    def write(self, text):
        # 发出内容
        self.newText.emit(str(text))

    def flush(self):  # real signature unknown; restored from __doc__
        """ flush(self) """
        pass


# 功能函数执行线程
class MyThread(QThread):  # 线程类
    def __init__(self):
        super(MyThread, self).__init__()
        self.is_on = True

    def run(self):  # 线程执行函数
        self.handle = ctypes.windll.kernel32.OpenThread(  # @UndefinedVariable
            win32con.PROCESS_ALL_ACCESS, False, str(QThread.currentThread()))
        while self.is_on:
            # function code
            train_saxs(data_dir="./data_split_test/saxs/train", epochs=5)
            self.is_on = False #训练完成后,终止线程的执行
            

# GUI代码        
class GenMast(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

        # Custom output stream.
        self.sm = Stream()
        self.sm.newText.connect(self.onUpdateText)
        sys.stdout = self.sm
        sys.stderr = self.sm

        self.my_thread = MyThread()
        # 拓展:线程结束后执行的操作
        self.my_thread.finished.connect(self.thread_finish_process)

    def onUpdateText(self, text):
        """Write console output to text widget."""
        cursor = self.process.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.process.setTextCursor(cursor)
        self.process.ensureCursorVisible()

    def closeEvent(self, event):
        # Return stdout to defaults.
        sys.stdout = sys.__stdout__
        super().closeEvent(event)
	
    def initUI(self):
        """Creates UI window on launch."""
        # Button for generating the master list.
        btnGenMast = QPushButton('Run', self)
        btnGenMast.move(450, 50)
        btnGenMast.resize(100, 200)
        btnGenMast.clicked.connect(self.genMastClicked)

        # Create the text output widget.
        self.process = QTextEdit(self, readOnly=True)
        self.process.ensureCursorVisible()
        self.process.setLineWrapColumnOrWidth(500)
        self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
        self.process.setFixedWidth(400)
        self.process.setFixedHeight(200)
        self.process.move(30, 50)

        # Set window size and title, then show the window.
        self.setGeometry(300, 300, 600, 300)
        self.setWindowTitle('Generate Master')
        self.show()

    def train_and_echo_to_gui(self):
        self.my_thread.start()

	def thread_finish_process(self):
		print("thread is end...")

    def genMastClicked(self):
        """Runs the main function."""
        print('Begin.')
        self.train_and_echo_to_gui()
        print('Done.')

if __name__ == '__main__':
    # Run the application.
    app = QApplication(sys.argv)
    app.aboutToQuit.connect(app.deleteLater)
    gui = GenMast()
    sys.exit(app.exec_())       

参考

https://blog.csdn.net/weixin_42532587/article/details/105689637
https://blog.csdn.net/ccj15010192778/article/details/102704301
https://blog.csdn.net/qq_47203885/article/details/110676076
https://zhuanlan.zhihu.com/p/373032781

你可能感兴趣的:(Qt,Python,TensorFlow,tensorflow,python,pyqt,gui,thread)