Использование потока в приложении с графическим интерфейсом - PullRequest
0 голосов
/ 09 ноября 2019

Я делаю несколько игр. Мне нужно принять команду от клиента. Это означает, что у меня есть GUI и TcpServer. Поэтому мне нужно работать с ними одновременно. Я использовал Thread, но он не работает. Не могли бы вы помочь мне найти проблему? Подводя итоги: во-первых, игрок нажимает кнопку «онлайн». Затем запускается функция Oyun () Gui и кнопка, связанная с функцией connectPressed (). В этой функции есть поток для запуска чтения клиентских команд, когда работает Gui.

Во-первых, я использовал QTimer, чтобы принимать команду от Клиента каждую 1 секунду. Но мой графический интерфейс завис. А потом я использовал QThread, но, согласно моим исследованиям, QThread не подходит для приложения с графическим интерфейсом. Итак, я нашел Qtconcurrent, QFutureWatcher и QFuture. Но моя нить все еще не работает. Я должен был где-то ошибиться.

#include <QApplication>
#include <anaclass.h>
#include <player2.h>
#include <tcpserver.h>
#include <QThread>
#include <QObject>
//#include <worker.h>

AnaClass *anaclass;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    anaclass = new AnaClass();
    anaclass->show();
    anaclass->Giris();   //button selection page

    return a.exec();
}
#include "anaclass.h"

Puan *puanlama1;
Puan *puanlama2;
player2 *yilan2;


AnaClass::AnaClass() : QGraphicsView()
{
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setFixedSize(800,600);

    scene = new QGraphicsScene;
    scene->setSceneRect(0,0,800,600);
    setScene(scene);
}

void AnaClass::Giris()
{
    connectButton = new Button("Online");
    double cxPos = this->width()/2 - connectButton->boundingRect().width()/2;
    double cyPos= 425;
    connectButton->setPos(cxPos, cyPos);
    connect(connectButton, SIGNAL(clicked()), this, SLOT(connectPressed()));
    scene->addItem(connectButton);
}

void AnaClass::Oyun()
{
    scene->clear();

    puanlama1 = new Puan();
    puanlama1->setDefaultTextColor(Qt::blue);
    puanlama1->setPos(5, 2);
    scene->addItem(puanlama1);

    yilan = new Yilan();
    yilan->setRect(0,0,19,19);
    scene->addItem(yilan);

    yilan->setFlags(QGraphicsItem::ItemIsFocusable);
    yilan->setFocus();

    QBrush brush;
    brush.setStyle(Qt::SolidPattern);
    brush.setColor(Qt::blue);
    yilan->setBrush(brush);
    if(stringButtonName == "Player2" || stringButtonName == "Online")
    {
    yilan->setPos(scene->width()/2 + 60, scene->height()/2);
    }
    else
    {
     yilan->setPos(scene->width()/2, scene->height()/2);
    }

    if(stringButtonName == "Player2" || stringButtonName == "Online")
    {
    yilan->playerNumber=1;

    puanlama2 = new Puan();
    puanlama2->setDefaultTextColor(Qt::green);
    puanlama2->setPos(700, 2);
    scene->addItem(puanlama2);

    yilan2 = new player2();
    yilan2->setRect(0,0,19,19);
    scene->addItem(yilan2);

    yilan2->setFlags(QGraphicsItem::ItemIsFocusable);
    yilan2->setFocus();

    QBrush brush2;
    brush2.setStyle(Qt::SolidPattern);
    brush2.setColor(Qt::green);
    yilan2->setBrush(brush2);
    yilan2->setPos(scene->width()/2 - 60,scene->height()/2);

    }

    emit emitTcp();
}

void AnaClass::connectPressed()
{
    qDebug()<<"connect basildi";
    server = new TCPServer();
    server->Test();
    stringButtonName = connectButton->buttonName;

    qDebug()<<"Gelen Veri " + server->OkunanBilgi;
    QFutureWatcher<void> watcher;
    connect(&watcher, SIGNAL(finished()), server, SLOT(daimaOku()), Qt::QueuedConnection);
    QFuture<void> deneme = QtConcurrent::run(this, &AnaClass::emitTcp);
    watcher.setFuture(deneme);
    Oyun();
}
}
#ifndef ANACLASS_H
#define ANACLASS_H

#include <QGraphicsScene>
#include <QGraphicsView>
#include <yilan.h>
#include <Meyve.h>
#include <QBrush>
#include <Puan.h>
#include <player2.h>
#include <QThread>
#include <label.h>
#include <QKeyEvent>
#include <button.h>
#include <QDebug>
#include <tcpserver.h>
#include <QTime>
#include <QTimer>
#include <QMutex>
//#include <worker.h>
#include <QFuture>
#include <QtConcurrent>
#include <QFutureWatcher>

class AnaClass : public QGraphicsView
{
    Q_OBJECT

public:
    AnaClass();
    void Giris();
    void Oyun();
    void timerEvent(QTimerEvent *event);
    void keyPressEvent(QKeyEvent *event2);

public:
    Yilan *yilan;
    //QThread *thread;
    QGraphicsScene *scene;
    Label *label1;
    Button* player1Button;
    Button* player2Button;
    Button* connectButton;
    TCPServer *server;
    QTimer *timerOnline;


public:
    int k=0;
    int t=0;
    QString stringButtonName;

signals:
    void emitTcp();

public slots:
    void connectPressed();
    void player1Pressed();
    void player2Pressed();
};
#endif // ANACLASS_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QObject>
#include <QTimer>

class TCPServer : public QObject
{
    Q_OBJECT
public:
    TCPServer(QObject* parent = nullptr);
    void Test();

signals:
    //void emitTcp();

public slots:
    void newConnection();
    void daimaOku();  // always read as english

public:
    QTcpServer *server;
    QTcpSocket *socket;
    QTimer *timerTcp;
    QString OkunanBilgi;

};
#endif // TCPSERVER_H
#include "tcpserver.h"

TCPServer::TCPServer(QObject * parent) : QObject()
{

}

void TCPServer::Test()
{
    server = new QTcpServer();

    connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));

    if(!server->listen(QHostAddress::Any, 1234))
    {
        qDebug()<<"server baslamadi";
    }
    else
    {
        qDebug()<<"server basladi";
    }

    //timerTcp = new QTimer();
    //connect(timerTcp, SIGNAL(timeout()), this, SLOT(daimaOku()));
    //emit emitTcp();
}

void TCPServer::newConnection()
{
    qDebug()<<"newconnection";
 socket = server->nextPendingConnection();
 socket->write("Merhaba Client");
 socket->flush();

 socket->waitForBytesWritten(5000);

 timerTcp->start(50);
}

void TCPServer::daimaOku()  //alwaysread() as english
{
      qDebug()<<"always read function is working";

//    if(socket->state() == QAbstractSocket::ConnectedState)
//    {
//    qDebug()<<"Daima oku fonsiyonu soket bagli";
//    socket->waitForReadyRead();
//    OkunanBilgi = socket->readAll();
//    qDebug()<<"Tcp daima oku :" + OkunanBilgi;
//    }
}

1 Ответ

0 голосов
/ 09 ноября 2019

Спасибо за ваши комментарии. Я решил проблему, удалив QFuture и добавив connect (), как показано ниже.

timerOnline = new QTimer();
connect(timerOnline, SIGNAL(timeout()), server, SLOT(daimaOku()));
timerOnline->start(500);

Но у меня есть другая проблема. Когда клиент подключается к серверу, мое приложение Gui зависает. Вы можете найти исправленный код ниже.

void TCPServer::daimaOku()
{
  qDebug()<<"Function is running";
  if(socket->state() == QAbstractSocket::UnconnectedState)
  {
  qDebug()<<"Socket is not connected";
  }
  else
  {
      qDebug()<<"Socket connected";
      socket->waitForReadyRead();
      OkunanBilgi = socket->readAll();
      qDebug()<<"Tcp always read :" + OkunanBilgi;
  }

}

Когда клиент не подключен, вывод:

Функция работает

СокетНе подключен

Разъем не подключен ...

Я могу играть в игру, но когда клиент подключен, игра зависает. Я не понимаю почему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...