发送自定义 PyQt 信号?
我正在通过制作一个简单的 Twitter 客户端来练习 PyQt 和 (Q) 线程。我有两个 Qthread。
主/GUI 线程。
Twitter 获取线程 - 每 X 分钟从 Twitter 获取数据。
因此,每隔 X 分钟我的 Twitter 线程就会下载一组新的状态更新(Python 列表)。我想将此列表移交给主/GUI 线程,以便它可以使用这些状态更新窗口。
我假设我应该使用信号/槽系统将“状态”Python 列表从 Twitter 线程传输到主/GUI 线程。所以,我的问题有两个:
如何从 Twitter 线程发送状态?
如何在主/GUI 线程中接收它们?
据我所知,PyQt 默认情况下只能通过信号/槽发送 PyQt 对象。我想我应该以某种方式注册一个自定义信号,然后我可以发送该信号,但是我发现的有关此的文档对于像我这样的新手来说非常不清楚。我订购了一本 PyQt 书,但一周后才到,我不想等到那时。 :-)
我在 Ubuntu 上使用 PyQt 4.6-1
更新:
这是来自不起作用的代码的摘录。首先,我尝试将信号(“newStatuses”,我刚刚编写的名称)“连接”到 Main/GUI 线程中的 self.update_tweet_list 函数:
QtCore.QObject.connect(self.twit_in,
QtCore.SIGNAL("newStatuses (statuses)"),
self.update_tweet_list)
然后,在 Twitter 线程中,我执行以下操作:
self.emit(SIGNAL("newStatuses (statuses)"), statuses)
当这一行是调用后,我收到以下消息:
QObject::connect: Cannot queue arguments of type 'statuses'
(Make sure 'statuses' is registered using qRegisterMetaType().)
我搜索了 qRegisterMetaType(),但没有找到任何我能理解的与 Python 相关的内容。
I'm practicing PyQt and (Q)threads by making a simple Twitter client. I have two Qthreads.
Main/GUI thread.
Twitter fetch thread - fetches data from Twitter every X minutes.
So, every X minutes my Twitter thread downloads a new set of status updates (a Python list). I want to hand this list over to the Main/GUI thread, so that it can update the window with these statuses.
I'm assuming that I should be using the signal / slot system to transfer the "statuses" Python list from the Twitter thread, to the Main/GUI thread. So, my question is twofold:
How do I send the statuses from the Twitter thread?
How do I receive them in the Main/GUI thread?
As far as I can tell, PyQt can by default only send PyQt-objects via signals / slots. I think I'm supposed to somehow register a custom signal which I can then send, but the documentation on this that I've found is very unclear to a newbie like me. I have a PyQt book on order, but it won't arrive in another week, and I don't want to wait until then. :-)
I'm using PyQt 4.6-1 on Ubuntu
Update:
This is an excert from the code that doesn't work. First, I try to "connect" the signal ("newStatuses", a name I just made up) to the function self.update_tweet_list in the Main/GUI thread:
QtCore.QObject.connect(self.twit_in,
QtCore.SIGNAL("newStatuses (statuses)"),
self.update_tweet_list)
Then, in the Twitter thread, I do this:
self.emit(SIGNAL("newStatuses (statuses)"), statuses)
When this line is called, I get the following message:
QObject::connect: Cannot queue arguments of type 'statuses'
(Make sure 'statuses' is registered using qRegisterMetaType().)
I did a search for qRegisterMetaType() but I didn't find anything relating to Python that I could understand.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你也可以这样做,这更加Pythonic(并且可读!)。
You can also do this, which is much more pythonic (and readable!).
当您在 PyQt 中使用这些旧式信号/槽时,实际上根本不需要声明类型。这些应该可以工作:
在这种情况下,PyQt 将在您发出信号时动态地为您创建一个新的信号类型。如果您想使用新型信号,那么它看起来更像是:
When you're using these old-style signals/slots in PyQt, there's actually no need to declare types at all. These should work:
In this case, PyQt will just create a new signal type for you on the fly when you emit the signal. If you wanted to user the new-style signals, then it would look more like:
从这个例子:
http://doc.qt.digia.com/4.5/qmetatype。 html
你可以用Python写下
编辑
从评论中提取的答案:
From this example:
http://doc.qt.digia.com/4.5/qmetatype.html
You can write down in Python
Edit
The answer extracted from the comment:
查看这个 问题我不久前问过。有一个代码示例可以帮助您弄清楚需要做什么。
您所说的关于注册信号的内容让我想到了这段代码(来自上述问题):
我在示例中传递字符串,但您应该能够将
str
替换为list< /代码>。
如果事实证明您无法传递可变对象,您可以按照我在示例中的方式处理结果(即在线程中设置一个
results
变量,告诉主线程它们已准备好,并让主线程“捡起它们”)。更新:
您收到消息
QObject::connect:无法对类型为“statuses”的参数进行排队
,因为您需要定义该参数的类型当你发出信号时你就会通过。您要传递的类型是list
而不是statuses
。当您连接信号时,它应该如下所示:
当您发出信号时,它应该如下所示:
鉴于
statuses
是一个列表。请注意,您可能希望根据您的情况发出列表的深层副本。更新2:
好的,使用
list
作为类型不正确。来自 PyQt4 帮助参考:Check out this question I asked a while back. There is a code example that might help you figure out what you need to do.
What you said about registering your signal makes me think of this code (from the aforementioned question):
I'm passing strings in my example, but you should be able to replace
str
withlist
.If it turns out that you can't pass mutable objects, you can handle your results the way I do in my example (i.e. set a
results
variable in the thread, tell the main thread that they are ready, and have the main thread "pick them up").Update:
You get the message
QObject::connect: Cannot queue arguments of type 'statuses'
because you need to define the type of argument that you will pass when you emit your signal. The type you want to pass islist
notstatuses
.When you connect your signal it should look like this:
When you emit your signal it should look like this:
given that
statuses
is a list. Note that you may want to emit a deep copy of your list depending on your situation.Update 2:
Ok, using
list
as the type is not correct. From the PyQt4 help reference:(Py)Qt 信号和槽跨线程工作与在单线程中一样。所以没有什么特别需要设置的:
在主线程中定义一个槽(方法),并将线程的信号连接到这个槽(连接也应该在主线程中完成)。然后,在线程中,当您想要时,只需发出信号即可工作。 这是关于在 PyQt 中使用带有线程的信号和槽的教程。
我建议您先在一个小玩具示例上尝试一下,然后再转向您的应用程序。
(Py)Qt signals and slots work cross-threads just the same as in a single thread. So there's nothing really special to set up:
Define a slot (method) in the main thread, and connect the thread's signal to this slot (the connection shall be also done in the main thread). Then, in the thread, when you want to, just emit the signal and it should work. Here's a tutorial on using signals and slots with threading in PyQt.
I recommend you to try it on a small toy example first, before moving to your application.