pyqt 5 popup button stop button

0

I have the following:

when executing the file

main.py

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog

from PyQt5 import uic

import subvent

class Principal(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        uic.loadUi('conexion.ui', self)

        self.boton.clicked.connect(self.invocar)
        self.Sub = subvent.Subvent()

    def invocar(self):
        self.Sub.exec_()

app = QApplication(sys.argv)
ventana = Principal()
ventana.show()
app.exec_()

I press the connect button and open subvent.py

from PyQt5.QtWidgets import QDialog
from PyQt5 import uic
import time
class Subvent(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        uic.loadUi('ventana.ui', self)

        self.valor = 0
        self._auto(self.valor)

        self.boton_parar.clicked.connect(self.ocultar)
        self.boton_inicio.clicked.connect(self.inicio)

    def ocultar(self):

        self.valor = 1
        #self.close()
        #self.linea.setEnabled(False)
        self._auto(self.valor)
    def inicio(self):

        self.valor = 2
        self._auto(self.valor)

    def _auto(self, dato):

       for x in range (0,5):

            if  self.valor == 2:
                #self.caja.setText('inicio')
                self.caja.setText(str('x='))
                print ('vuelta  ', x)
                time.sleep(1)
            elif self.valor == 1:
                #self.caja.setText('parar')
                print ('llego  parar')
                self.close()
                break

I leave you an image so you have an idea

Well the case is that when you press start and this is running the count of returns for now only 5 (but the idea is that they are more), you can stop that account. I have not been able to achieve it because when you execute the program and give it to stop, you only do it when you finish counting.

While the for (is counting) is running, the buttons and windows are disabled and it does not let me press stop.

can only be done at the end of the for

    
asked by omardread 11.05.2018 в 15:36
source

1 answer

0

It is the old error so common in the programming of GUIs, you are blocking the main loop of the app. Every application has a main cycle in charge of drawing the interface and responding to the generated events, to initiate this cycle it is responsible for app.exec_() precisely. The main loop should never be blocked or the application will be frozen and will stop responding.

time.sleep is bloquenate (like input for example), this means that it does not return until the time spent as an argument has not passed. Any function that does not return "immediately" and that is not executed asynchronously will block the execution of the code at that point until it returns.

If your app is going to be limited to a counter, the simplest option is to do without time.sleep and one cycle for and use QtCore.Qtimer :

from PyQt5.QtWidgets import QDialog
from PyQt5.QtCore import QTimer
from PyQt5 import uic



class Subvent(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        uic.loadUi('ventana.ui', self)

        self._running = None
        self._vuelta = None

        self.boton_parar.clicked.connect(self.ocultar)
        self.boton_inicio.clicked.connect(self.inicio)

        self._timer = QTimer()
        self._timer.timeout.connect(self._auto)


    def ocultar(self):
        self._running = False


    def inicio(self):
        self._vuelta = 0
        self._running = True
        self.caja.setText('Iniciada')
        self._timer.start(1000)


    def _auto(self):
        if self._vuelta <= 5:
            if  self._running:
                self.caja.setText('x = {}'.format(self._vuelta))
                self._vuelta += 1

            else:
                self._timer.stop()
                self.caja.setText('Detenida')
        else:
            self._timer.stop()
            self.close()

If in each "turn" you think about doing some task that takes a long time to return then you will have to execute it asynchronously, using a thread for example. You can look at this answer from me to another question where, as an example, a thread is used to implement a counter as well.

    
answered by 11.05.2018 / 17:19
source