gpt4 book ai didi

gtk - 如何在 GTK/QT/Clutter 应用程序中使用 ZeroMQ?

转载 作者:行者123 更新时间:2023-12-04 13:06:24 24 4
gpt4 key购买 nike

gtk应用程序的所有执行都发生在 gtk_main 内功能。其他图形框架作品也有类似的事件循环,如 app.execQTclutter_mainClutter .然而ZeroMQ是基于假设存在 while (1) ...它被插入的循环(例如参见 here 示例)。

你如何结合这两种执行策略?

我目前想在用 C 编写的杂乱应用程序中使用 zeromq,所以我当然希望直接回答这个问题,但也请添加其他变体的答案。

最佳答案

将 zmq 和 gtk 或 clutter 结合的正确方法是将 zmq 队列的文件描述符连接到主事件循环。可以通过使用检索 fd

int fd;
size_t sizeof_fd = sizeof(fd);
if(zmq_getsockopt(socket, ZMQ_FD, &fd, &sizeof_fd))
perror("retrieving zmq fd");

将它连接到主循环是使用 io_add_watch 的问题:
GIOChannel* channel = g_io_channel_unix_new(fd);    
g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP, callback_func, NULL);

在回调函数中,需要先检查是否真的有东西要读,然后再读。否则,该函数可能会阻塞等待 IO。
gboolean callback_func(GIOChannel *source, GIOCondition condition,gpointer data)
{
uint32_t status;
size_t sizeof_status = sizeof(status);

while (1){
if (zmq_getsockopt(socket, ZMQ_EVENTS, &status, &sizeof_status)) {
perror("retrieving event status");
return 0; // this just removes the callback, but probably
// different error handling should be implemented
}
if (status & ZMQ_POLLIN == 0) {
break;
}

// retrieve one message here
}
return 1; // keep the callback active
}

请注意:这并没有经过实际测试,我从 Python+Clutter 做了一个翻译,这是我使用的,但我很确定它会起作用。
作为引用,以下是实际工作的完整 Python+Clutter 代码。
import sys
from gi.repository import Clutter, GObject
import zmq

def Stage():
"A Stage with a red spinning rectangle"
stage = Clutter.Stage()

stage.set_size(400, 400)
rect = Clutter.Rectangle()
color = Clutter.Color()
color.from_string('red')
rect.set_color(color)
rect.set_size(100, 100)
rect.set_position(150, 150)

timeline = Clutter.Timeline.new(3000)
timeline.set_loop(True)

alpha = Clutter.Alpha.new_full(timeline, Clutter.AnimationMode.EASE_IN_OUT_SINE)
rotate_behaviour = Clutter.BehaviourRotate.new(
alpha,
Clutter.RotateAxis.Z_AXIS,
Clutter.RotateDirection.CW,
0.0, 359.0)
rotate_behaviour.apply(rect)
timeline.start()
stage.add_actor(rect)

stage.show_all()
stage.connect('destroy', lambda stage: Clutter.main_quit())
return stage, rotate_behaviour

def Socket(address):
ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.setsockopt(zmq.SUBSCRIBE, "")
sock.connect(address)
return sock

def zmq_callback(queue, condition, sock):
print 'zmq_callback', queue, condition, sock

while sock.getsockopt(zmq.EVENTS) & zmq.POLLIN:
observed = sock.recv()
print observed

return True

def main():
res, args = Clutter.init(sys.argv)
if res != Clutter.InitError.SUCCESS:
return 1

stage, rotate_behaviour = Stage()

sock = Socket(sys.argv[2])
zmq_fd = sock.getsockopt(zmq.FD)
GObject.io_add_watch(zmq_fd,
GObject.IO_IN|GObject.IO_ERR|GObject.IO_HUP,
zmq_callback, sock)

return Clutter.main()

if __name__ == '__main__':
sys.exit(main())

关于gtk - 如何在 GTK/QT/Clutter 应用程序中使用 ZeroMQ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6452131/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com