no he hecho demasiado desarrollo Qt hace poco, pero si no recuerdo mal, puede llamar QApplication::processEvents()
dentro de su propio bucle de eventos (en lugar de empezar el bucle principal de Qt a través QApplication::exec()
)
Editar: Yo aproveché la oportunidad de una lenta mañana de domingo para probar/aprender algo sobre PyQt (enlaces de Python para Qt) y compilé un código de prueba de concepto a continuación. Reemplazar la llamada a QApplication::exec()
con un bucle de evento personalizado basado en QApplication::processEvents()
parece funcionar.
También he buscado rápidamente simpleeventloop.cpp
y tpclient-cpptext main.cpp
. Por lo que parece, debería estar bien simplemente agregar QApplication::processEvents()
en algún lugar del lazo principal de SimpleEventLoop::runEventLoop()
. Para añadirlo al bucle principal, probablemente reemplace el intervalo tv
para la función select()
en lines 106
through 117
con
tv.tv_sec = 0;
tv.tv_usec = 10000; // run processEvents() every 0.01 seconds
app->processEvents();
y cambiar la firma en line 89
a void SimpleEventLoop::runEventLoop(QApplication *app)
. Debería estar bien agregar las cosas de Qt habituales a su implementación del cliente (su reemplazo de tpclient-cpptext main.cpp
)
Parece un truco, sin embargo. Probablemente comenzaría con algo como esto para empezar. Creo que su idea de ajustar TPSocket
y el temporizador dentro de los conceptos de Qt para enviarlos con el QAbstractEventDispatcher
al QEventLoop
es la mejor solución a largo plazo. Entonces debería ser suficiente que su runEventLoop()
simplemente llame al QApplication::exec()
. Pero nunca antes había usado QAbstractEventDispatcher
, así que tome mis comentarios por lo que son.
import sys
import time
from PyQt4 import QtGui
from PyQt4 import QtCore
# Global variable used as a quick and dirty way to notify my
# main event loop that the MainWindow has been exited
APP_RUNNING = False
class SampleMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
global APP_RUNNING
APP_RUNNING = True
# main window
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Test')
self.statusBar().showMessage('Ready')
# exit action (assumes that the exit icon from
# http://upload.wikimedia.org/wikipedia/commons/b/bc/Exit.png
# is saved as Exit.png in the same folder as this file)
exitAction = QtGui.QAction(QtGui.QIcon('Exit.png')
,'Exit'
,self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
self.connect(exitAction
,QtCore.SIGNAL('triggered()')
,QtCore.SLOT('close()'))
# main menu
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
# toolbar
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)
# text editor
textEdit = QtGui.QTextEdit()
self.setCentralWidget(textEdit)
#tool tip
textEdit.setToolTip('Enter some text')
QtGui.QToolTip.setFont(QtGui.QFont('English', 12))
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self
,'Message'
,"Are you sure?"
,QtGui.QMessageBox.Yes
,QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
global APP_RUNNING
APP_RUNNING = False
else:
event.ignore()
# main program
app = QtGui.QApplication(sys.argv)
testWindow = SampleMainWindow()
testWindow.show()
# run custom event loop instead of app.exec_()
while APP_RUNNING:
app.processEvents()
# sleep to prevent that my "great" event loop eats 100% cpu
time.sleep(0.01)
Si bien mi objetivo es utilizar AbstractEventDispatcher para integrar correctamente eventloop, soy demasiado principiante en Qt para llevarlo a cabo rápidamente. Estoy tratando de hacer esto a un lado mientras obtengo una solución funcional. Estoy intentando hackear la clase SimpleEventLoop para que pueda devolver su estado "en ejecución" que luego se puede comprobar desde la aplicación principal con una instrucción while similar a su ejemplo. Te dejaré saber cómo funciona. Lo que más me preocupa es si las llamadas de señal de Boost se manejarán correctamente desde la aplicación Qt y de qué forma. – mhilmi
@Gimpyfuzznut: agregué un truco de muestra para simpleeventloop.cpp. Es probable que el truco sugerido sea más complicado, porque la implementación actual de SimpleEventLoop :: runEventLoop() implementa un bucle de evento estándar (consulte, por ejemplo, http://stackoverflow.com/questions/658403/how-would-you-implement-a- basic-event-loop/658495 # 658495 para obtener una explicación) y, por lo tanto, nunca regresa a menos que una señal o un temporizador invoquen SimpleEventLoop :: endEventLoop() como parte del bucle de evento en ejecución. – stephan