2

Я делаю легкую графическую программу с PyQT5.Как приостановить/воспроизвести поток в PyQT5?

Но теперь у меня возникла проблема с потоком.

Я только что сделал простую тестовую программу, как внизу:

программа просто пытается добавить цифры в текстовое поле, но он выходит из строя.

Я не знаю, почему, но каким-то образом я могу предотвратить ее, удалив комментарий (time.sleep)

import sys 
import threading 
import time 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 

class Some(QWidget): 
    e = threading.Event() 

    def btnfunc(self): 
     self.e.set()   

    def __init__(self): 
     super().__init__() 
     self.myButton = QPushButton('do next') 
     self.logs = QTextEdit() 

     self.mylay = QVBoxLayout() 
     self.mylay.addWidget(self.myButton) 
     self.mylay.addWidget(self.logs) 

     self.setLayout(self.mylay) 
     self.setGeometry(300, 300, 300, 550) 
     self.setWindowTitle('mytest') 
     self.show() 
     t = threading.Thread(target=self.myfunc, args=()) 
     t.start() 
     self.myButton.clicked.connect(self.btnfunc) 

    def myfunc(self): 
     for i in range(300): 
      # time.sleep(0.4) 
      self.logs.append(str(i)) 
      if i == 20: 
       self.e.wait() 

app = QApplication(sys.argv) 
ex = Some() 
sys.exit(app.exec_()) 

Было бы лучше, если наборы раз выше.

Я думал, что это из-за доступа к ресурсам, так как это pyQT5 GUI.

Итак, я нашел QThread. и я пробовал как дно,

import sys 
import time 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 

class Some(QWidget): 
    qw = QWaitCondition() 
    qm = QMutex() 

    def btnfunc(self): 
     self.qw.wakeAll() 

    def __init__(self): 
     super().__init__() 
     self.myButton = QPushButton('do next') 
     self.logs = QTextEdit() 

     self.mylay = QVBoxLayout() 
     self.mylay.addWidget(self.myButton) 
     self.mylay.addWidget(self.logs) 

     self.setLayout(self.mylay) 
     self.setGeometry(300, 300, 300, 550) 
     self.setWindowTitle('mytest') 
     self.show()  
     self.myButton.clicked.connect(self.btnfunc) 

     self.thread = QThread() 
     self.thread.started.connect(self.myfunc) 
     self.thread.start() 

    def myfunc(self): 
     for i in range(300): 
      self.logs.append(str(i)) 
      if i == 20: 
       self.qw.wait(self.qm) 

app = QApplication(sys.argv) 
ex = Some() 
sys.exit(app.exec_()) 

Но аварии, не работает. и попробовал QThread + threading.Event(). Он замораживает графический интерфейс.

Теперь я не знаю, как поступить ... это

Edit: Я только что понял, о потоке. Нельзя получить доступ из другой темы, кроме QThread. Затем я буду продолжать поиск QWaitCondition

+1

Куда деградирует и с каким сообщением? Можете ли вы, возможно, выбросить еще больше ненужных материалов из примеров, чтобы они стали проще? – Trilarion

+0

@Trilarion Это не было из сообщения. Я просто понял, что это связано с безопасностью потока QWidget. Спасибо за ваш комментарий кстати. – user3524577

ответ

2

Вы не должны контролировать GUI напрямую через многопоточность. Поскольку два разных потока пытаются управлять графическим интерфейсом, это приводит к зависанию или сбою. Я узнал об этой концепции отсюда http://www.xyzlang.com/python/PyQT5/pyqt_multithreading.html

Вот ваш код, который будет работать отлично.

import sys 
import threading 
import time 
from PyQt5.QtCore import * 
from PyQt5.QtWidgets import * 

# Added new 
class Communicate(QObject): 
    signal = pyqtSignal(str) 

class Some(QWidget): 
    e = threading.Event() 

    def btnfunc(self): 
     self.e.set()   

    def __init__(self): 
     super().__init__() 

     #communicate object 
     self.comm = Communicate() 
     self.comm.signal.connect(self.append_data) 

     self.myButton = QPushButton('do next') 
     self.logs = QTextEdit() 

     self.mylay = QVBoxLayout() 
     self.mylay.addWidget(self.myButton) 
     self.mylay.addWidget(self.logs) 

     self.setLayout(self.mylay) 
     self.setGeometry(300, 300, 300, 550) 
     self.setWindowTitle('mytest') 
     self.show() 
     t = threading.Thread(target=self.myfunc, args=()) 
     t.start() 
     self.myButton.clicked.connect(self.btnfunc) 

    def myfunc(self): 
     for i in range(300): 
      # time.sleep(0.4) 
      #self.logs.append(str(i)) 
      self.comm.signal.emit(str(i)) 
      if i == 20: 
       self.e.wait() 

    def append_data(self, data): 
     self.logs.append(data) 

app = QApplication(sys.argv) 
ex = Some() 
sys.exit(app.exec_()) 
+0

Спасибо. Я был глуп. Действительно полезно. – user3524577

+0

@ Kaushal Вы не используете фактический модуль потоковой передачи pyqt5. Вы используете фактический модуль потоковой передачи python. Может ли он работать с помощью 'QThread'? –

Смежные вопросы