#c #multithreading #qt
#c #многопоточность #qt
Вопрос:
Я не знаю, следует ли мне использовать потоки в консольном приложении. Когда я выбираю вариант 1 для ЗАПУСКА КЛИЕНТА, он запускает клиент и получает сообщения с сервера…
этот метод называется connectClient из варианта коммутатора 1 :
void App::connectClient(){
if (this->client == NULL){
this->client = new Client(QUrl(QStringLiteral("ws://localhost:10000")), 0);
connect(this->client, SIGNAL(messageHasCome()), this, SLOT(listenToMessage()));
qWarning() << "CLIENT IS CONNECTING TO PORT: 10000";
}
else {
qWarning() << "CAREFULL, CLIENT IS ALREADY CONNECTED AT PORT: 10000";
emit signalShowMenu();
}
}
ПРОБЛЕМА в том, что даже при подключении сигнального слота, когда сообщение отправляется с сервера, оно не перейдет в listenToMessage(), только один раз в начале. Итак, я подумал, что если это произошло только один раз, возможно, он не сможет получить сигнал с сервера, потому что у него нет собственного потока? когда я делал это в приложении с графическим интерфейсом, это работало, и каждый раз, когда с сервера поступало сообщение, оно отображалось в TextEdit.
Это мое приложение:
У меня есть меню для консольного приложения:
consoleApp.cpp
m_out << "n************MENU*****************n";
m_out << "(1): START CLIENTn";
m_out << "(2): SHOW MESSAGE FROM CLIENTn";
m_out << "(3): SEND MESSAGEn";
m_out << "(4): EXITn";
m_out << "************************************n";
m_out.flush();
m_in >> m_choice;
Мой коммутатор решает, что делать:
switch (m_choice)
{
case 1:
m_App->connectClient();
break;
case 2:
m_out << m_App->getMessageFromServer();
m_out.flush();
showMenu();
break;
case 3:
sendMessagetoServerOptionChoosen();
showMenu();
break;
case 4:
exit(EXIT_FAILURE);
break;
default:
// showMenu();
break;
}
Итак, что я хотел бы сделать, это: всякий раз, когда доступно сообщение с сервера (signal messageHasCome()), он будет выдавать сигнал listenToMessage(), даже когда я нахожусь в своем меню… Должен ли я использовать потоки? Я в замешательстве, не могли бы вы объяснить мне, как это работает?
Спасибо
ПРАВКА1
Теперь я пытаюсь следовать, я добавил это в класс, где находится мое меню:
class App_console : public QObject {
Q_OBJECT
QThread appThread;
в меню я добавил это:
switch (m_choice)
{
case 1:
//want to start a new thread here.
m_App->moveToThread(amp;appThread);//
appThread.start(); //
m_App->connectClient();
break;
Чего мне не хватает… ? Я хочу добавить в другой поток объект m_App или просто метод m_App-> connectClient(); как я мог это сделать?
Комментарии:
1. Если вы активно ожидаете ввода пользователем и блокируете основной поток для этого, то да. вам нужен другой поток для выполнения этой работы.
2. @Hayt ок, я сейчас читаю о темах в Qt5.7, у вас есть какие-нибудь предложения? должен ли я создавать потоки везде, где я использую сигнальную систему слотов?
3. Попробуйте прочитать документацию Qt и взглянуть на примеры. Обычно это помогает начать работу. doc.qt.io/qt-5/threads-technologies.html
Ответ №1:
Я решил свою проблему:
consoleApp.cpp
В конструктор я добавил это, поэтому я переместил объект m_App в поток appThread, затем я подключил сигналы и слоты, и это работает … сигнал от ConsoleApp и слот от m_App, так что это означает, что когда я вызываю сигнал из ConsoleApp, он запускает процессы из объекта m_App
/****************************THREAD STUFF*****************/
m_App->moveToThread(amp;appThread);
connect(who,signal,who, slot);
appThred.start();
/*******************************************************/