组合一个外部事件循环与Qt的 [英] Combing an External Event Loop with Qt's

查看:186
本文介绍了组合一个外部事件循环与Qt的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为开源客户端/服务器4X策略游戏( Thousand Parsec )构建一个Qt客户端。这是Google Summer of Code项目。但我被困在一个死胡同。基本上,客户端通过便于客户端/服务器通信的C ++协议层与服务器接口。协议的文档可从此处获得。



现在我的问题是协议要求你创建一个虚拟EventLoop类的子类(链接)。有一个用于同一链接上的控制台客户端的SimpleEventLoop示例。我很难弄清楚如何设计我自己的事件循环子类来处理协议的事件,同时挂钩到Qt应用程序。我的研究使我相信 QAbstractEventDispatcher 是我想使用的Qt类,但文档看起来很苗条,我我不知道我该怎么做。



有没有人有将外部事件循环与Qt应用程序连接的经验?我还在Qt页面上找到了这个示例,但它不是很有帮助 - 或者至少我真的不明白。



谢谢!

解决方案

我最近没有做过太多的Qt开发,但如果我记得正确,你可以调用 QApplication :: processEvents() .qtsoftware.com / 4.5 / qapplication.html#execrel =nofollow> QApplication :: exec()



编辑:我使用了一个缓慢的星期天早上的机会,来测试/学习 PyQt (Python绑定Qt)和拼凑在一起的概念验证码下面。用基于 QApplication :: processEvents()的自定义事件循环替换对 QApplication :: exec()的调用 工作。



我也很快看到了 simpleeventloop.cpp tpclient-cpptext main.cpp 。从它的外观,只要在 SimpleEventLoop :: runEventLoop()的主循环中添加 QApplication :: processEvents() 。要将它添加到主循环,我可能会替换 c c> c> href =http://git.thousandparsec.net/gitweb/gitweb.cgi?p=libtpproto-cpp.git;a=blob;f=tpproto/simpleeventloop.cpp;hb=ebfc08b322c552d73d34a368cca0623782f8d3f8#l106 =nofollow >行 106 c>



<$ p $ p> tv.tv_sec = 0;
tv.tv_usec = 10000; //每0.01秒运行processEvents()
app-> processEvents();

并更改 89 void SimpleEventLoop :: runEventLoop(QApplication * app)。在您的客户端实现中添加您常用的Qt内容(您替换 tpclient-cpptext main.cpp



看起来像个黑客。我可能会开始这样的事情开始。我认为您的包装 TPSocket 和Qt各自概念中的计时器,以便使用 QAbstractEventDispatcher QEventLoop 是更好的长期解决方案。这样就足够了你的 runEventLoop()只是调用 QApplication :: exec()。但我从来没有使用过 QAbstractEventDispatcher ,所以请把我的意见,他们是什么。

  import sys 
导入时间

从PyQt4导入QtGui
从PyQt4导入QtCore

#全局变量用作一个快速和脏的方式以通知我的
#main事件循环MainWindow已退出
APP_RUNNING = False

类SampleMainWindow(QtGui.QMainWindow):
def __init __ = None):
QtGui.QMainWindow .__ init __(self)
全局APP_RUNNING
APP_RUNNING = True

主窗口
self.setGeometry(300,
self.setWindowTitle('Test')
self.statusBar()。showMessage('Ready')

#退出动作图标来自
#http://upload.wikimedia.org/wikipedia/commons/b/bc/Exit.png
#作为Exit.png保存在与此文件相同的文件夹中)
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 b
$ b#main menu
menubar = self.menuBar()
fileMenu = menubar.addMenu('& File')
fileMenu.addAction(exitAction)

#toolbar
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAction)

#文本编辑器
textEdit = QtGui.QTextEdit()
self.setCentralWidget(textEdit)

#tool tip
textEdit.setToolTip('输入一些文本')
QtGui.QToolTip。 setFont(QtGui.QFont('English',12))

def closeEvent(self,event):
reply = QtGui.QMessageBox.question(self
,'Message'
,你确定吗?
,QtGui.QMessageBox.Yes
,QtGui.QMessageBox.No)

如果回复== QtGui.QMessageBox.Yes:
event.accept()
全局APP_RUNNING
APP_RUNNING = False
else:
event.ignore()

#main程序
app = QtGui.QApplication(sys.argv)
testWindow = SampleMainWindow()
testWindow.show()
#运行自定义事件循环而不是app.exec_()
而APP_RUNNING:
app.processEvents()
#sleep以防止我的大事件循环使用100%cpu
time.sleep(0.01)


I'm building a Qt client for the open-source client/server 4X strategy game Thousand Parsec. This a Google Summer of Code project. I'm however stuck at a dead end. Basically, the client interfaces with the server via a C++ protocol layer that facilitates client/server communication. The protocol's documentation is available here.

Now my problem is that the protocol requires you to create a subclass of the virtual EventLoop class (link) in your client. There is an example SimpleEventLoop used for console clients on the same link. I'm having difficulty figuring out how I can design my own event loop subclass that handles the protocol's events while hooking into the Qt application at the same time. My research has lead me to believe QAbstractEventDispatcher is the Qt class I want to use but the documentation seems pretty slim and I'm not exactly sure how I would go about doing this.

Does anyone else have experience linking external event loops with a Qt application? I've also found this example on the Qt page but it wasn't very helpful - or at least I didn't really understand it.

Thanks!

解决方案

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)

这篇关于组合一个外部事件循环与Qt的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆