用Qt组合外部事件循环

mhi*_*lmi 30 c++ events qt

我正在为开源客户端/服务器4X策略游戏Thousand Parsec构建一个Qt客户端.这是Google Summer of Code项目.然而,我却陷入了死胡同.基本上,客户端通过C++协议层与服务器连接,以促进客户端/服务器通信.该协议的文档可在此处获得.

现在我的问题是该协议要求您在客户端中创建虚拟EventLoop类(链接)的子类.在同一链接上有一个用于控制台客户端的SimpleEventLoop示例.我很难弄清楚如何设计我自己的事件循环子类来处理协议的事件,同时挂钩到Qt应用程序.我的研究让我相信QAbstractEventDispatcher是我想要使用的Qt类,但是文档似乎相当渺茫,我不确定如何去做这个.

有没有其他人有经验将外部事件循环与Qt应用程序链接?我也在Qt页面上找到了这个例子,但它没有太大帮助 - 或者至少我没有真正理解它.

谢谢!

ste*_*han 33

我最近没有做过太多的Qt开发,但是如果我没记错的话,你可以QApplication::processEvents()在你自己的事件循环中调用(而不是启动Qt主循环QApplication::exec())

编辑:我利用一个缓慢的星期天早上的机会来试驾/学习一些关于PyQt(Qt的Python绑定)的东西,并在下面拼凑出一个概念验证代码.QApplication::exec()用基于的自定义事件循环替换调用QApplication::processEvents() 似乎工作.

我也迅速地看着simpleeventloop.cpptpclient-cpptext main.cpp.从它的外观来看,只需QApplication::processEvents()在主循环中添加一些内容即可SimpleEventLoop::runEventLoop().将其添加到主循环中,我可能会更换tv为间隔select()功能106通过117

tv.tv_sec = 0;
tv.tv_usec = 10000;   // run processEvents() every 0.01 seconds
app->processEvents();
Run Code Online (Sandbox Code Playgroud)

在更改签名89void SimpleEventLoop::runEventLoop(QApplication *app).将常用的Qt内容添加到客户端的实现(替换tpclient-cpptext main.cpp)应该没那么好

看起来像是一个黑客.我可能会从这样的事情开始.我认为你TPSocket在Qt各自的概念中包装和计时器的想法是为了将它们转发QAbstractEventDispatcherQEventLoop更好的长期解决方案.那么你应该runEventLoop()只是打电话就足够了QApplication::exec().但我以前从未使用QAbstractEventDispatcher过,所以请注意我们的意见.

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)
Run Code Online (Sandbox Code Playgroud)