我正在学习Qt,我正在阅读来自Qt wiki的线程,事件和QObjects,并遵循wiki建议如何在一段时间内处理某些工作,但它不适合我的具体情况。这是我目前正在努力实现的一个简单例子。
class FooEvents : public FooWrapper {
public virtual serverTime(..) { std::cout << "Server time event\n"; }
public virtual connected(..) { std::cout << "Connected event\n"; }
}
class Foo : public QObject {
private:
FooAPI *client;
public:
Foo(FooEvents *ev, QObject *parent = 0) : client(new FooApi(ev)) { .. }
private slots:
void processMessages() {
if (state is IDLE)
reqFooAPiServerTime();
select(client->fd()+1, ...);
if (socket is ready for read)
client.onReceive();
}
public:
void connect(...) {
if (connection) {
QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(processMessages()));
timer.start(1000); // I don't get the output from FooEvents
}
}
}
这很简单,但我认为这说明了我的情况。为什么这不起作用以及我必须处理这种情况的其他替代方案? Thanks.s
编辑:每秒都会调用processMessages,但我没有从事件中获得任何输出
答案 0 :(得分:2)
timer
在哪里声明和定义?
如果它在Foo::connect()
的本地,它将在它有机会射击之前被摧毁。据推测,它只需要成为Foo
类的成员对象。
另请注意,QObject
为计时器提供了自己的简单接口 - 只需覆盖受保护的虚拟timerEvent()
函数,然后调用QObject的startTimer()
即可开始获取这些计时器事件。在这种情况下,它们不会有一个接收计时器事件的插槽,而是最终会被覆盖的timerEvent()
函数:
protected:
void timerEvent(QTimerEvent *event) {
processMessages();
}
public:
void connect( /* ... */ ) {
// ...
startTimer(1000);
}
答案 1 :(得分:1)
这不起作用,因为processMessages()不是SLOT
。
So Declare processMessages() as a private slot and then try.
答案 2 :(得分:0)
您不会将计时器声明为插槽。在标题中,您必须声明:
class ... {
QTimer timer;
...
private slots:
void processMessages();
...
};
然后记得建立SIGNAL-SLOT连接并配置计时器:
connect(&timer, SIGNAL(timeout()), this, SLOT(processMessages()));
timer.setInterval(1000);
timer.start();
timer.start(1000);
也是有效的......
另一个可能性
其他可能性是使用与每个Q_OBJECT关联的计时器并重载timerEvent
:
class ... {
Q_OBJECT
...
protected:
void timerEvent(QTimerEvent *event);
...
};
然后你必须实现这样的计时器事件:
void MyClass::timerEvent(QTimerEvent *event) {
processMessages();
}
您可以通过简单调用startTimer(1000);