使用Qthread运行一个函数

时间:2015-02-14 14:40:35

标签: c++ qt qthread

我想连续运行一个类的函数作为一个线程,直到该类的对象被销毁。

client.h

class client:public QWidget
{
   Q_OBJECT
   public:
   //some declarations

   client();
   void setclientui();
   //some ui elements
   void receiveme();  //i want this function to be run as a thread 
                      //It has to be run continuously to receive 
                      //messages from socket and when a message is 
                      //received ,it must display it in the gui.

 public slots:
   int prework();
   void sendme();
};

注意:receiveme()使用recv()个tcp套接字,在收到消息之前会被阻止。

client.cpp

 void receiveme(){
 while(1){
    if(recv(sockfd,receivebuf,1024,0)<0)
    {
        qDebug()<<errno;
        break;
    }
   receivebuf[20]='\0';
    qDebug()<<receivebuf;
   outputbox->append(a);
}}

mainwindow.h

  class MainWindow : public QMainWindow
{
   Q_OBJECT
public:
   Dialog* newdialog;//join a new chat
QString ipp,portt;
QTabWidget *wdg;
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
    void receivesocketaddress();
void on_actionJoin_a_chat_triggered();
};

mainwindow.cpp

   MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
    wdg=new QTabWidget;
   ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionJoin_a_chat_triggered()
{
    newdialog=new Dialog();
    newdialog->setWindowTitle("Join a chat");
    newdialog->setModal(true);
    qDebug()<< QObject::connect(newdialog->conne,SIGNAL(clicked()),this,SLOT(receivesocketaddress()));
   newdialog->exec();
}
 void MainWindow::receivesocketaddress()
{
     client *aclient=new client;
     aclient->iptoconnect=newdialog->ip->text().toLocal8Bit().data();
     aclient->porti=newdialog->port->text().toLocal8Bit().data();
     if(aclient->prework()==0)//ie connected
     {
        newdialog->close();
        wdg->addTab(aclient,tr("new chat"));
        setCentralWidget(wdg);
        //here the ui is shown.Now the aclient->receiveme() should
        //running
     }
     else
     {
        newdialog->displayerror();
        layout->addWidget(error,3,0,2,2);
        qDebug()<<"cud not connect";
     }

}

如果aclient->prework()==0然后显示了一个gui但是我怎么能在这个时候运行aclient->receiveme()作为一个线程,以便它继续运行并从socket读取消息。如果收到一条消息,它应该在gui中显示。

没有线程,gui会冻结。我试图使用QThread::movetothread()但是我收到以下错误

QThread::cannot move object with parent

并且要使用子类方法,client类必须继承QThread但由于它已经继承QWidget,因此抛出以下错误

call to QObject is ambiguous

我如何在这里使用QThread?

1 个答案:

答案 0 :(得分:2)

  1. 窗口小部件只能在GUI线程中运行,因此您需要将client实现为QObject子类,并通过信号/插槽连接与UI进行通信。 Qt不允许你在非UI线程中执行outputbox->append(a)(假设此处outputboxQWidget};
  2. 您可能甚至不需要在这里使用线程 - Qt提供了自己的基于事件(信号/插槽)API的套接字类;
  3. 如果您仍然需要在不同的线程中使用recv(),则需要继承QThread(一种方法)或QObject(另一种方法);在这两种情况下,您都需要像messageReceived(QByteArray)这样的信号连接到UI对象中将处理消息的插槽;所以receiveme()插槽可能如下所示:

    void client::receiveme() { while(1){ if(recv(sockfd,receivebuf,1024,0)<0) { qDebug()<<errno; break; } receivebuf[20]='\0'; QByteArray msg(receivebuf); emit messageReceived(msg); } }

  4. article可能会有所帮助