Qt 4.7 中不阻塞 ui 的网络

发布于 2024-10-05 01:24:57 字数 1058 浏览 6 评论 0原文

我有一个可以连接多个客户端的服务器。客户端是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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤寂小茶 2024-10-12 01:24:57

最好的事情是永远不要调用像 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.

苏佲洛 2024-10-12 01:24:57

我不建议在构造函数中启动线程。

像这样初始化它:

Client * client = new Client();
client->moveToThread(client);
client->start();

或者如果您不想使用这样的解决方案,请在 start();this->moveToThread(this); 之前添加构造函数

upd:抱歉,我第一次没有看到你有这个字符串。

I don't recommend start thread in constructor.

Initialize it like:

Client * client = new Client();
client->moveToThread(client);
client->start();

Or if you don't want to use such solution, add in constructor before start(); line this->moveToThread(this);

upd: sorry, i didn't saw at first time, that you have this string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文