No se puede agregar un botón en un hilo de PyQt5.
No entendí por qué este código no funciona.
import sys
from threading import Thread
from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Mi App")
self.setFixedSize(QSize(400, 300))
Thread(target=self.AddButton).start()
def AddButton(self):
button = QPushButton("Presióname", self)
print("Ok")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
Y alguien me dijo que tenía que usar señales porque no puedo modificar la interfaz de usuario desde hilos externos, así que hice este ejemplo pero aún no funcionó.
class WorkerSignals(QObject):
starting = pyqtSignal()
class Worker(QRunnable):
def __init__(self):
super(Worker, self).__init__()
self.signals = WorkerSignals()
@pyqtSlot()
def run(self):
self.signals.starting.emit()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Mi App")
self.setFixedSize(QSize(400, 300))
self.threadpool = QThreadPool()
worker = Worker()
worker.signals.starting.connect(self.makebutton)
self.threadpool.start(worker)
def makebutton(self):
button = QPushButton("Presióname", self)
print("gad")
Si alguien puede ayudar, sería encantador.
davy.ai
El problema con el código original es que intenta modificar la IU desde un hilo separado, lo cual no está permitido en PyQt. El enfoque recomendado es utilizar señales y ranuras para comunicarse entre hilos y actualizar la IU desde el hilo principal.
En el código de ejemplo actualizado, se crea una clase
Worker
para ejecutar la funciónmakebutton
en un hilo separado. Se crea la claseWorkerSignals
para definir las señales disponibles. Estas señales se conectan a ranuras en la claseMainWindow
, que actualizan la IU en consecuencia.Sin embargo, todavía hay un problema con el código actualizado. La función
makebutton
crea un widgetQPushButton
en el hilo separado, lo cual no está permitido. Cualquier creación de elementos de IU debe realizarse en el hilo principal. Para resolver este problema, la funciónmakebutton
puede emitir una señal con la información necesaria para crear el botón en el hilo principal. La claseMainWindow
puede luego conectar esta señal a una ranura que crea el botón.Aquí hay un ejemplo de código actualizado que debería funcionar: