0

I need to show in the main GUI what is happening in a thread. Opening a dialog box loads a table from a database (in the original code, I put the fixed values ​​here to simplify the code). Pressing load should show the current values ​​of code, second, A and B in the main GUI. In addition, at the end of the duration corresponding to the first row, it must continue with the second automatically and so on until the last, with the possibility of pausing, resuming or canceling at any time. At the end everything must be reported in the main GUI.

I am trying to do this using Thread Class but I cannot make the system continue automatically after the end of the first duration value ... Nor can I from said class indicate in the GUI that the process ended since it is not possible to use Signal- Slot in the Thread Class. If anyone knows how to do it I would appreciate it ...

Sorry if you don't understand what I'm looking for, I'm using a translator ... I paste the test code:

import sys, re
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from threading import *
import time


class MainApp(QMainWindow):
    def __init__(self, parent=None, *args):
        super(MainApp, self).__init__(parent)
        
        self.dialogo = Dialogo()


        self.setFixedSize(1000, 800)      
        
        self.button_1 = QPushButton(self)        
        self.button_1.setGeometry(20, 20, 140, 30)     
        self.button_1.setText("Mostrar Dialogo")
        self.button_1.clicked.connect(self.muestra_dialogo)

        self.label_codigo = QLabel(self)      
        self.label_codigo.setGeometry(20, 500, 120, 30)
        self.label_codigo.setText("Codigo actual")
        self.label_codigo.setAlignment(Qt.AlignCenter)

        self.label_duracion = QLabel(self)      
        self.label_duracion.setGeometry(220, 500, 120, 30)
        self.label_duracion.setText("Segundo actual")
        self.label_duracion.setAlignment(Qt.AlignCenter)
        
        self.label_A = QLabel(self)       
        self.label_A.setGeometry(360, 500, 120, 30)
        self.label_A.setText("A")
        self.label_A.setAlignment(Qt.AlignCenter)

        self.label_B = QLabel(self)        
        self.label_B.setGeometry(500, 500, 120, 30)
        self.label_B.setText("B")
        self.label_B.setAlignment(Qt.AlignCenter)
        
        self.label_valor_codigo = QLabel(self)        
        self.label_valor_codigo.setGeometry(20, 550, 120, 30)
        self.label_valor_codigo.setText("")
        self.label_valor_codigo.setAlignment(Qt.AlignCenter)

        self.label_valor_duracion = QLabel(self)       
        self.label_valor_duracion.setGeometry(220, 550, 120, 30)
        self.label_valor_duracion.setText("")
        self.label_valor_duracion.setAlignment(Qt.AlignCenter)
        
        self.label_valor_A = QLabel(self)      
        self.label_valor_A.setGeometry(360, 550, 120, 30)
        self.label_valor_A.setText("")
        self.label_valor_A.setAlignment(Qt.AlignCenter)

        self.label_valor_B = QLabel(self)       
        self.label_valor_B.setGeometry(500, 550, 120, 30)
        self.label_valor_B.setText("")
        self.label_valor_B.setAlignment(Qt.AlignCenter)
        
        self.button_2 = QPushButton(self)        
        self.button_2.setGeometry(150, 700, 100, 30)     
        self.button_2.setText("Pausa")
        self.button_2.setEnabled(False) 
        self.button_2.clicked.connect(self.pausa)
        
        self.button_3 = QPushButton(self)        
        self.button_3.setGeometry(300, 700, 100, 30)    
        self.button_3.setText("Reanudar")
        self.button_3.setEnabled(False)
        self.button_3.clicked.connect(self.reanudar)
        
        self.button_4 = QPushButton(self)        
        self.button_4.setGeometry(450, 700, 100, 30)    
        self.button_4.setText("Detener")
        self.button_4.setEnabled(False)
        self.button_4.clicked.connect(self.detener)

        
        self.button_5 = QPushButton(self)        
        self.button_5.setGeometry(600, 700, 100, 30)     
        self.button_5.setText("Salir")
        self.button_5.clicked.connect(self.salir)         
        
    def muestra_dialogo(self):                
        
        self.dialogo.Signal_Step.connect(self.ejecuta_step)  
        self.dialogo.show()

    def pausa(self):
        self.c.pause()
        self.button_2.setEnabled(False)
        self.button_3.setEnabled(True)
                
    def reanudar(self):
        self.c.resume()
        self.button_3.setEnabled(False)
        self.button_2.setEnabled(True)
                        
    def detener(self):
        self.c.kill()
        self.button_4.setEnabled(False)
        self.button_2.setEnabled(False)
        self.button_3.setEnabled(False)
        
        
    def salir(self):
        self.dialogo.close()
        self.close()
        self.c.kill()        
        
    def ejecuta_step(self, steps_codificado, i):
        global duracion
        self.button_2.setEnabled(True)
        self.button_3.setEnabled(False)
        self.button_4.setEnabled(True)
        
        if i == 0:
            print ('parar')

        else:
                                      
            cantidad_pasos = len(steps_codificado)
            if i <= cantidad_pasos:
                codigo = steps_codificado[i-1]
                duracion = int(str(codigo)[:2])
                A = int(str(codigo)[2:4])
                B = int(str(codigo)[4:6])
                print("Codigo: " + str(codigo))
                print("Paso número: " + str(i))
                print("Duración: " + str(duracion) + " segundos")
                print("A: " + str(A))
                print("B: " + str(B))
                
                self.label_valor_codigo.setText(str(codigo))
                self.label_valor_A.setText(str(A))
                self.label_valor_B.setText(str(B))
                              
                self.c = CountdownThread(duracion, steps_codificado, i)
                self.c.start()

            else:
                print ('parar')


class Dialogo(QDialog):
    Signal_Step = pyqtSignal(list, int)
    
    def __init__(self):
      QDialog.__init__(self)

      self.setFixedSize(600, 350)
      self.move(120, 150)      
      self.setWindowFlags((Qt.FramelessWindowHint))
      self.setStyleSheet("background-color: rgba(57, 239, 255, 100)")

      self.label_titulo_Rutinas = QLabel(self)
      self.label_titulo_Rutinas.setGeometry(0, 0, 600, 30)
      self.label_titulo_Rutinas.setText("Tabla")
      self.label_titulo_Rutinas.setAlignment(Qt.AlignCenter)

      self.tabla = QTableWidget(self)

      self.tabla.setEditTriggers(QAbstractItemView.NoEditTriggers)
      self.tabla.setSelectionBehavior(QAbstractItemView.SelectRows)
      self.tabla.setSelectionMode(QAbstractItemView.NoSelection)
      self.tabla.setColumnCount(4)
      self.tabla.setRowCount(8)
      self.tabla.horizontalHeader().setDefaultAlignment(Qt.AlignHCenter|Qt.AlignVCenter|
                                                          Qt.AlignCenter)
      self.tabla.horizontalHeader().setHighlightSections(False)
      self.tabla.verticalHeader().setVisible(False)
      self.tabla.verticalHeader().setDefaultSectionSize(20)
      nombreColumnas = ("Codigo Step", "Duracion", "A", "B")
      self.tabla.setHorizontalHeaderLabels(nombreColumnas)          
      self.tabla.setColumnWidth(0, 140)
      self.tabla.setColumnWidth(1, 90)
      self.tabla.setColumnWidth(2, 90)
      self.tabla.setColumnWidth(3, 90)
      
      self.tabla.setItem(0,0, QTableWidgetItem("050814"))
      self.tabla.setItem(0,1, QTableWidgetItem("05"))
      self.tabla.setItem(0,2, QTableWidgetItem("08"))
      self.tabla.setItem(0,3, QTableWidgetItem("14"))
      self.tabla.setItem(1,0, QTableWidgetItem("040302"))
      self.tabla.setItem(1,1, QTableWidgetItem("04"))
      self.tabla.setItem(1,2, QTableWidgetItem("03"))
      self.tabla.setItem(1,3, QTableWidgetItem("02"))
      self.tabla.setItem(2,0, QTableWidgetItem("080706"))
      self.tabla.setItem(2,1, QTableWidgetItem("08"))
      self.tabla.setItem(2,2, QTableWidgetItem("07"))
      self.tabla.setItem(2,3, QTableWidgetItem("06"))
      self.tabla.setItem(3,0, QTableWidgetItem("060812"))
      self.tabla.setItem(3,1, QTableWidgetItem("06"))
      self.tabla.setItem(3,2, QTableWidgetItem("08"))
      self.tabla.setItem(3,3, QTableWidgetItem("12"))      
      
      self.tabla.resize(412, 200)
      self.tabla.move(100, 60)
      self.button_load = QPushButton(self)
      self.button_load.setGeometry(150, 300, 80, 25)
      self.button_load.setText("Cargar")
      self.button_load.clicked.connect(self.envia_valores)    
      self.button_cancel = QPushButton(self)
      self.button_cancel.setGeometry(350, 300, 80, 25)
      self.button_cancel.setText("Cancelar")
      self.button_cancel.clicked.connect(self.cancelar)

    def envia_valores(self):
        steps_codificado = ["050814", "040302", "080706", "060812"] #In the real code these values come from a database ...
        i = 1
        self.Signal_Step.emit(steps_codificado, i)

    def cancelar(self):             
        self.close()

class CountdownThread(Thread):
    
    def __init__(self, n, steps_codificado, i):
        super().__init__()
        self.n = n
        self.steps_codificado = steps_codificado
        self.i = i
        self.is_paused = False
        self.is_killed = False
          
    def run(self):
        while self.n > 0:
            print('Segundo actual: ' + str(self.n))
            self.n -= 1
            time.sleep(1)
            if self.is_paused:
                self.n += 1            
            
            if self.is_killed:
                break    
        if self.n == 0:
                print('final')
                #here it should show in the main GUI a message that the step completed or the total of steps!!!
                #also must do button_2, button_3, button_4.setEnabled(False)

    def pause(self):
        self.is_paused = True
        print("Pausado") 
        
    def resume(self):
        self.is_paused = False

    def kill(self):
        self.is_killed = True
        print("Detenido por el usuario")
 

if __name__ == "__main__":        
    app = QApplication(sys.argv)
    window = MainApp()
    window.show()
    app.exec_()
musicamante
  • 31,222
  • 5
  • 26
  • 48
dangusting
  • 11
  • 2
  • Use `QThread` from QtCore instead of python `Thread`, then add a custom signal to that class (similar to what you did for `Signal_Step`) and emit it when required. – musicamante Nov 29 '21 at 12:35

0 Answers0