Je n'ai pas fait trop de développement Qt récemment, mais si je me souviens bien, vous pouvez appeler QApplication::processEvents()
au sein de votre propre boucle d'événements (au lieu de commencer la boucle principale Qt par QApplication::exec()
)
Edit: I J'ai utilisé l'opportunité d'un dimanche matin pour tester/apprendre quelque chose sur PyQt (bindings Python pour Qt) et bricoler ensemble un code de preuve de concept ci-dessous. Remplacement de l'appel à QApplication::exec()
avec une boucle d'événement personnalisé basé sur QApplication::processEvents()
semble pour fonctionner. J'ai également regardé rapidement simpleeventloop.cpp
et tpclient-cpptext main.cpp
. D'après les apparences, il serait bon d'ajouter QApplication::processEvents()
quelque part dans la boucle principale de SimpleEventLoop::runEventLoop()
. Pour ajouter à la boucle principale, je remplacerais probablement l'intervalle tv
pour la fonction select()
en lines 106
through 117
avec
tv.tv_sec = 0;
tv.tv_usec = 10000; // run processEvents() every 0.01 seconds
app->processEvents();
et changer la signature line 89
à void SimpleEventLoop::runEventLoop(QApplication *app)
. Il devrait être bien d'ajouter vos trucs Qt habituels à votre implémentation du client (votre remplacement de tpclient-cpptext main.cpp
)
Cela ressemble à un hack, cependant. Je commencerais probablement avec quelque chose comme ça pour commencer. Je pense que votre idée d'emballage TPSocket
et le minuteur dans les concepts respectifs de Qt afin de les transmettre avec le QAbstractEventDispatcher
au QEventLoop
est la meilleure solution à long terme. Il devrait alors être suffisant que votre runEventLoop()
appelle simplement QApplication::exec()
. Mais je n'ai jamais utilisé QAbstractEventDispatcher
auparavant, alors prenez mes commentaires pour ce qu'ils sont.
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)
Alors que mon objectif est d'utiliser le AbstractEventDispatcher pour intégrer correctement le eventloop, je suis trop débutant à Qt pour le décrocher rapidement. J'essaie de faire cela sur le côté tout en obtenant une solution de travail en place. J'essaie de pirater la classe SimpleEventLoop afin qu'elle puisse retourner son statut "en cours d'exécution" qui peut ensuite être vérifié depuis l'application principale avec une instruction while similaire à votre exemple. Je vous ferai savoir comment cela fonctionne. La chose qui m'inquiète est de savoir si et comment les rappels du signal Boost seront traités correctement depuis l'application Qt. – mhilmi
@Gimpyfuzznut: ajout d'un exemple de hack pour simpleeventloop.cpp. Votre hack suggéré est probablement plus compliqué, car l'implémentation actuelle de SimpleEventLoop :: runEventLoop() implémente une boucle d'événement standard (voir par exemple http://stackoverflow.com/questions/658403/how-would-you-implement-a- basic-event-loop/658495 # 658495 pour une explication), et ne retourne donc jamais, sauf si un signal ou un temporisateur appelle SimpleEventLoop :: endEventLoop() dans le cadre de la boucle d'événement en cours d'exécution. – stephan