I haven't done too much Qt development recently, but if I remember correctly, you can call QApplication::processEvents()
within your own event loop (instead of starting the Qt main loop through QApplication::exec()
)
Edit: I have used the opportunity of a slow Sunday morning to test-drive / learn something about PyQt (Python bindings for Qt) and cobbled together a proof-of-concept code below. Replacing the call to QApplication::exec()
with a custom event loop based on QApplication::processEvents()
seems to work.
I have also quickly looked at simpleeventloop.cpp
and tpclient-cpptext main.cpp
. From the looks of it, it shoud be fine to just add QApplication::processEvents()
somewhere in the main loop of SimpleEventLoop::runEventLoop()
. To add it to the main loop, I would probably replace the tv
interval for the select()
function in lines 106
through 117
with
tv.tv_sec = 0;
tv.tv_usec = 10000; // run processEvents() every 0.01 seconds
app->processEvents();
and change the signature in line 89
to void SimpleEventLoop::runEventLoop(QApplication *app)
. It should than be fine to add your usual Qt stuff to your implementation of the client (your replacement of tpclient-cpptext main.cpp
)
Looks like a hack, though. I would probably start with something like this to get started. I think that your idea of wrapping TPSocket
and the timer within Qt's respective concepts in order to forward them with the QAbstractEventDispatcher
to the QEventLoop
is the better long-term solution. It should then be sufficient that your runEventLoop()
simply calls QApplication::exec()
. But I have never used QAbstractEventDispatcher
before, so take my comments for what they are.
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)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…