簡體   English   中英

在 GUI 應用程序中使用線程

[英]Using Thread in GUI application

我正在制作一個多人游戲。 我需要接受客戶的命令。 這意味着我有 GUI 和 TcpServer。 所以我需要同時工作。 我使用了線程,但它不起作用。 你能幫我找出問題嗎? 總結:首先玩家按下“在線”按鈕。 然后 Oyun() Gui function 運行,按鈕與 connectPressed() function 連接。 在這個 function 中有一個線程,以便在 Gui 工作時運行讀取客戶端命令。

首先,我使用 QTimer 以每 1 秒從客戶端獲取命令。 但是我的 GUI 凍結了。 然后我使用了 QThread,但根據我的研究,QThread 不適合 GUI 應用程序。 所以我找到了 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;
//    }
}

謝謝您的意見。 我通過刪除 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;
  }

}

客戶端未連接時,output為:

Function 正在運行

套接字未連接

套接字未連接...

我可以玩游戲,但是當客戶端連接時,游戲凍結。 我不明白為什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM