pyqt 5 ventana emergente boton parar

publicado por: Anonymous

Tengo lo siguiente:

al ejecutar el archivo

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_()

presiono el boton conexion y abre
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

Les dejo una imagen para que tengan una idea

les dejo una imagen para  que tengan una idea

Bueno el caso es que al presionar inicio y este corriendo la cuenta de vueltas por ahora solo 5 (pero la idea es que sean mas), pueda parar esa cuenta.
no he podido lograrlo ya que al ejeutar el programa y darle parar solo lo hace cuando termina de contar.

mientras se ejecuta el for(esta contando), se deshabilitan los botones y ventanas y no me deja presionar parar.

solo se puede al finalizar el for

solución

Es el viejo error tan común en la programación de GUIs, estás bloqueando el main loop de la app. Toda aplicación tiene un ciclo principal encargado de dibujar la interfaz y de responder a los eventos generados, de iniciar este ciclo se encarga app.exec_() precisamente. El main loop jamás debe bloquearse o la aplicación quedará congelada y dejará de responder.

time.sleep es bloquenate (al igual que input por ejemplo), esto quiere decir que no retorna hasta que el tiempo pasado como argumento no a pasado. Cualquier función que no retorne de forma “inmediata” y que no sea ejecutada de forma asíncrona va a bloquear la ejecución del código en ese punto hasta que no retorne.

Si tu app se va a limitar a un contador la opción más simple es prescindir de time.sleep y un ciclo for y usar 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()

introducir la descripción de la imagen aquí

Si en cada “vuelta” piensas hacer alguna tarea que tarde en retornar entonces vas a tener que ejecutarla de forma asíncrona, usando un hilo por ejemplo. Puedes mirarte esta respuesta mía a otra pregunta donde como ejemplo se usa un hilo para implementar un contador también.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *