PyQt5中如何将LineEdit输入内容传入等待的input()函数
解决PyQt5中向后台线程的
input()传递LineEdit输入的问题 你原来的方法行不通,核心原因是**input()在调用时就已经绑定了当时的sys.stdin对象**,后续替换sys.stdin不会影响已经处于阻塞等待状态的那个input()调用。
下面给你两种可行的解决思路:
方法一:用线程安全队列替代input()
直接抛弃input(),改用queue.Queue在主线程和后台线程之间传递输入,逻辑更清晰直观:
修改后的完整代码:
import os import sys import queue from PyQt5.uic import loadUi from PyQt5.QtWidgets import QApplication import threading class App(): def __init__(self) -> None: self.ui_file = 'app.ui' self.app = QApplication(sys.argv) self.window = loadUi(os.path.join(os.path.dirname(__file__), self.ui_file)) self.window.pushButton.clicked.connect(self.connect) self.window.lineEdit_2.returnPressed.connect(self.enter) # 初始化线程安全队列,用来传递输入内容 self.input_queue = queue.Queue() def enter(self): command = self.window.lineEdit_2.text() self.window.lineEdit_2.setText("") # 将输入放入队列,唤醒后台等待的线程 self.input_queue.put(command + '\n') # 加换行符模拟终端输入的结束行为 def exec(self): self.window.show() self.app.exec_() def print(self, text): self.window.textBrowser.append(text) def connect(self): t = threading.Thread(target=self.run) t.start() def run(self): self.print('Password: ') # 等待队列中的输入,替代原本的input() password = self.input_queue.get().strip() self.print(f'password is {password}') def main(): app = App() app.exec() if __name__ == '__main__': main()
方法二:重定向sys.stdin到自定义类
如果一定要保留input()调用,可以自定义一个模拟标准输入的类,让它从队列读取内容:
import os import sys import queue from PyQt5.uic import loadUi from PyQt5.QtWidgets import QApplication import threading class QueueStdin: def __init__(self, input_queue): self.input_queue = input_queue def readline(self): # 阻塞等待队列输入,模拟标准输入的readline行为 return self.input_queue.get() class App(): def __init__(self) -> None: self.ui_file = 'app.ui' self.app = QApplication(sys.argv) self.window = loadUi(os.path.join(os.path.dirname(__file__), self.ui_file)) self.window.pushButton.clicked.connect(self.connect) self.window.lineEdit_2.returnPressed.connect(self.enter) self.input_queue = queue.Queue() # 替换系统标准输入为自定义类 sys.stdin = QueueStdin(self.input_queue) def enter(self): command = self.window.lineEdit_2.text() self.window.lineEdit_2.setText("") self.input_queue.put(command + '\n') def exec(self): self.window.show() self.app.exec_() def print(self, text): self.window.textBrowser.append(text) def connect(self): t = threading.Thread(target=self.run) t.start() def run(self): self.print('Password: ') # 正常使用input(),它会读取我们自定义的标准输入内容 password = input('Password: ') self.print(f'password is {password}') def main(): app = App() app.exec() if __name__ == '__main__': main()
两种方法都能解决问题,第一种更直接,避免了修改系统全局状态,推荐优先使用。
内容的提问来源于stack exchange,提问作者Sahar
相关产品推荐
相关产品推荐

