Qt 4.7 中不阻塞 ui 的网络
我有一个可以连接多个客户端的服务器。客户端是GUI,服务器是命令行。客户端有几个功能(例如连接和登录),当发送到服务器时应该收到回复。
基本上我需要运行 QTcpSocket 函数 waitForConnection 和 waitForReadyRead。但是,我需要在不阻塞 UI 的情况下执行此操作。
我想做的事情如下: 有一个类(客户端)实现 QThread 来完成所有等待。这是在 main 中创建的。
Client::Client (...)
{
moveToThread (this); // Not too sure what this does
mClient = new QTcpSocket (this);
start();
}
void Client::run (void)
{
exec();
}
void Client::connectToServer (...)
{
mClient->connectToHost (hostname, port);
bool status = mClient->waitForConnected (TIMEOUT);
emit connected (status);
}
void Client::login (...)
{
... Similar to connectToServer ...
}
然后,每当我准备好建立连接时,我都会运行 GUI(例如 ConnectToServerDialog)。我将“已连接信号”从线程连接到对话框,因此当我连接或连接超时时,它将发出此信号。
QMetaObject::invokeMethod (mClient, "connectToServer", Qt::QueuedConnection,
Q_ARG (const QString &, hostname), Q_ARG (quint16, port));
我遇到了断言失败(无法将事件发送到不同线程拥有的对象。)因为我对 Qt 相当陌生,所以我不知道我所做的是否是正确的事情。
有人可以告诉我我正在做的事情是否是一个好方法,如果是的话为什么我的程序会崩溃?
I have a server to which multiple clients can connect to. The client is GUI while the server is command line. The client has several functions (such as connect and login) which, when sent to the server should receive a reply.
Basically I need to run the QTcpSocket functions waitForConnection and waitForReadyRead. However, I need to do this without blocking the UI.
What I thought of doing was the following:
Have a class (Client) implement QThread which does all the waiting. This is created in main.
Client::Client (...)
{
moveToThread (this); // Not too sure what this does
mClient = new QTcpSocket (this);
start();
}
void Client::run (void)
{
exec();
}
void Client::connectToServer (...)
{
mClient->connectToHost (hostname, port);
bool status = mClient->waitForConnected (TIMEOUT);
emit connected (status);
}
void Client::login (...)
{
... Similar to connectToServer ...
}
Then the GUI (for example, ConnectToServerDialog) I run this whenever I am ready to make a connection. I connect the "connected signal" from the thread to the dialog so when I am connected or connection timed out it will emit this signal.
QMetaObject::invokeMethod (mClient, "connectToServer", Qt::QueuedConnection,
Q_ARG (const QString &, hostname), Q_ARG (quint16, port));
I am getting an assert failure with this (Cannot send events to objects owned by a different thread.) Since I am fairly new to Qt I don't know if what I am doing is the correct thing.
Can somebody tell me if what I am doing is a good approach and if so why is my program crashing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
最好的事情是永远不要调用像 waitForBlah() 这样的方法...强制事件循环等待一段不确定的时间会导致 GUI 在此期间冻结的可能性。相反,将 QTcpSocket 的 connect() 信号连接到某个插槽,该插槽将根据需要更新 GUI,并让事件循环照常继续。在该插槽内执行连接的操作。
The best thing is never to call methods like waitForBlah() ... forcing the event loop to wait for an undetermined period introduces the possibility of the GUI freezing up during that time. Instead, connect your QTcpSocket's connected() signal to some slot that will update your GUI as appropriate, and let the event loop continue as usual. Do your on-connected stuff inside that slot.
我不建议在构造函数中启动线程。
像这样初始化它:
或者如果您不想使用这样的解决方案,请在
start();
行this->moveToThread(this);
之前添加构造函数upd:抱歉,我第一次没有看到你有这个字符串。
I don't recommend start thread in constructor.
Initialize it like:
Or if you don't want to use such solution, add in constructor before
start();
linethis->moveToThread(this);
upd: sorry, i didn't saw at first time, that you have this string.