Сеть без блокировки пользовательского интерфейса в Qt 4.7 - PullRequest
0 голосов
/ 28 ноября 2010

У меня есть сервер, к которому могут подключиться несколько клиентов.Клиент с графическим интерфейсом, а сервер с командной строкой.У клиента есть несколько функций (таких как подключение и вход в систему), которые при отправке на сервер должны получать ответ.

В основном мне нужно запустить функции QTcpSocket waitForConnection и waitForReadyRead.Однако мне нужно сделать это, не блокируя пользовательский интерфейс.

Я подумал о следующем: пусть класс (клиент) реализует 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, я не знаю, является ли то, что я делаю, правильным делом.

Может кто-нибудь сказать мне, является ли то, что я делаю, хорошим подходом иесли так, то почему моя программа падает?

Ответы [ 2 ]

2 голосов
/ 29 ноября 2010

Лучше всего никогда не вызывать такие методы, как waitForBlah () ... заставляя цикл обработки ждать неопределенный период, и появляется возможность зависания GUI в течение этого времени.Вместо этого подключите сигнал connected () вашего QTcpSocket к некоторому слоту, который обновит ваш графический интерфейс соответствующим образом и позволит циклу обработки событий продолжаться как обычно.Делайте свои подключенные вещи внутри этого слота.

0 голосов
/ 28 ноября 2010

Я не рекомендую запускать поток в конструкторе.

Инициализируйте это как:

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

Или, если вы не хотите использовать такое решение, добавьте конструктор перед start(); строкой this->moveToThread(this);

upd: извините, я не видел в первый раз, что у вас есть эта строка.

...