客户端:
左右两边,比例为1:3,左边为聊天框TextBrowser和TextEdit,列表选择框按键和3个label,分别用于计时,显示玩家信息和显示图片,布局方式为竖直VBoxLayout,比例为3:1:1:1:1:3;右边为30*30的棋盘布局方式为网格GridLayout,整体为HBoxLayout。
widget.h#ifndef WIDGET_H #define WIDGET_H #include <QtGui/QWidget> #include <QTextBrowser> #include <QTextEdit> #include <QListWidget> #include <QPushButton> #include <QLabel> #include <QButtonGroup> #include <QVBoxLayout> #include <QHBoxLayout> #include <QGridLayout> #include <QPaintEvent> #include <QImage> #include <QPainter> #include <QMessageBox> #include <QTimerEvent> #include <QTimer> #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include "chessindividual.h" #include "mylabel.h" #include "thread.h" #include <QDebug> class MyTextEdit; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); Thread *th;//添加线程成员 private: //聊天信息显示 QTextBrowser *chatBrowser; //聊天输入 MyTextEdit *messageSend; //棋子个数列表 QListWidget *chessNumber; //开始按钮 QPushButton *startBtn; //计算时间 QLabel *timeLabel; //玩家提示信息 QLabel *playerLable; //玩家图片 MyLabel *imageLabel; //右边的棋盘部分 ChessIndividual *chessArea; //计时器 QTimer *timer; //时间 int sec; int min; //黑白子的标记 int flag; //闪烁的flag int blinkflag; //上次落子的位置 int lastTimePos; //timer的id int timerID; //闪烁 是否为第一个落子的标志 int count; //自己在服务器上的fd 区别玩家和观看者 //为了区分玩家和观看者,在主线程中设置了MyfdonServer默认值为2, //该客户端在服务器上的fd,如果是邀请者,邀请被对方同意,自己必然是玩家, //如果是被邀请者,同意对方的邀请,自己必然是玩家。根据这两个条件设置MyfdonServer,修改默认值。 //从而区分开玩家的客户端和观看者的客户端,并做相应的操作限制。 int myfdOnServer; //如果发送了#Agree信号的必然是玩家 //如果发送了#command 信号,并且收到#Agree信号的必然是玩家; //如果发送了#command 信号又收到了#disAgree信号必然不是玩家 protected: void timerEvent(QTimerEvent *); public slots: //聊天框的处理:向服务器发送聊天信息 void sendMsgToServer(QString); //start按钮的处理:向服务器发送信息#Command: void sendStartMsgToServer(); //接受到了开始的邀请命令,开启对话框 void JoinOrNot(int,int); //接收到了拒绝游戏的命令 void refuse(); //刷新计时器 void flushTime(); //开始游戏 void startGame(int); //向服务器发送坐标信息 void sendMyposition(int); //收到坐标信号在相应的位置画图 void getPos_and_paintImg(int); //收到赢家的fd void getWinnerInfo(int); }; //添加MyTextEdit类,继承于QTextEdit类。 //重写该类的KeyPressEvent方法, //使每次在TextEdit中按下回车键并有内容输入的时候发送信号, //把内容以QString类型的信号(sendChatMsg(QString))方式发给主线程。 //主线程接受的槽函数拿到信息并把它写给服务器。 class MyTextEdit: public QTextEdit{ Q_OBJECT//信号和槽的类都是必须的宏名 public: MyTextEdit(QWidget *parent = 0); protected: //重写键盘处理函数 void keyPressEvent(QKeyEvent *e); signals: void sendChatMsg(QString); //public slots: }; #endif // WIDGET_H
MyTextEdit.cpp
#include "widget.h" #include <QKeyEvent> /*MyTextEdit类继承了QTextEdit类,并重写keyPressEvent方法, 然后聊天的textEdit实例化为他的对象,就有了keyPressEvent的方法 当ENTER键按下的时候发送信号sendChatMeg(Qstring) , chatBrowser绑定该信号执行槽函数append()*/ MyTextEdit::MyTextEdit(QWidget *parent):QTextEdit(parent) { // w = (Widget *)parent; } void MyTextEdit::keyPressEvent(QKeyEvent *e){ if(e->key() == Qt::Key_Return){ //截除开始和结尾处的空白字符,过去掉 if(toPlainText().trimmed() == "") return; //把自己中的内容以信号的方式发送出去 emit sendChatMsg(this->toPlainText()); // toPlainText().toStdString().c_str(); // 将QString转换为const char * this->clear(); }else{ QTextEdit::keyPressEvent(e); } }
chessindividual.h
#ifndef CHESSINDIVIDUAL_H #define CHESSINDIVIDUAL_H #include <QWidget> #include <QPushButton> #include <QStackedLayout> #include <QButtonGroup> #include <QPixmap> class ChessIndividual : public QWidget { Q_OBJECT public: explicit ChessIndividual(QWidget *parent = 0); //按键组 QButtonGroup *BtnGroup; //900个按键 QPushButton *chessBtn[30][30]; }; #endif // CHESSINDIVIDUAL_H棋盘实现文件
chessindividual.cpp
#include "chessindividual.h" ChessIndividual::ChessIndividual(QWidget *parent) : QWidget(parent) { QGridLayout *glayout = new QGridLayout; glayout->setSpacing(0); glayout->setMargin(5); //右半边的900按钮 //添加按键组 BtnGroup = new QButtonGroup(this); int i,j; for(i=0;i<30;i++){ for(j=0;j<30;j++){ chessBtn[i][j]= new QPushButton(this); //通过判断这个checkable的属性,来确定这个键是不是已经设置了图标,即:是不是已落子 //它的默认值为false,现在把它改为true //用CSS修改了按钮的样子,用每个按钮的边画出虚线网格 chessBtn[i][j]->setCheckable(true); chessBtn[i][j]->setStyleSheet("border-radius:15px;border-top:1px dashed #000000;border-left:1px dashed #000000;background-color:#F5F5DC;"); if(i == 29){ chessBtn[i][j]->setStyleSheet("border-radius:15px;border-bottom:1px dashed #000000;border-top:1px dashed #000000;border-left:1px dashed #000000;background-color:#F5F5DC;"); }else if(j == 29){ chessBtn[i][j]->setStyleSheet("border-radius:15px;border-right:1px dashed #000000;border-top:1px dashed #000000;border-left:1px dashed #000000;background-color:#F5F5DC;"); } BtnGroup->addButton(chessBtn[i][j],i*30+j); chessBtn[i][j]->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); chessBtn[i][j]->setCursor(Qt::PointingHandCursor); glayout->addWidget(chessBtn[i][j],i,j); } } chessBtn[29][29]->setStyleSheet("border-radius:15px;border:1px dashed #000000;background-color:#F5F5DC;"); setLayout(glayout); }
myLabel,h
#ifndef MYLABEL_H #define MYLABEL_H #include <QPaintEvent> #include <QPainter> #include <QLabel> class MyLabel : public QLabel { Q_OBJECT public: explicit MyLabel(QWidget *parent = 0); QPixmap map1,map2; int flag;//角色标记 signals: public slots: private: protected: void paintEvent(QPaintEvent *); }; #endif // MYLABEL_H
#include "mylabel.h" #include <QDebug> MyLabel::MyLabel(QWidget *parent) : QLabel(parent),flag(0) { map1.load(":/mark.jpg"); map2.load(":/andy.jpg"); } void MyLabel::paintEvent(QPaintEvent *){ QPainter painter(this);//指定父控件 qDebug()<<"in Mylabel paintEvent!"; //将Map铺满整个组建 if(flag == 0){ painter.drawPixmap(0,0,this->width(),this->height(),map1); }else{ painter.drawPixmap(0,0,this->width(),this->height(),map2); } }
widget.cpp 客户端构造函数
#include "widget.h" Widget::Widget(QWidget *parent) : QWidget(parent),sec(0),min(0),flag(0),myfdOnServer(2),blinkflag(0),count(0) { resize(800,600); //左半边所有组件 chatBrowser = new QTextBrowser(this); chatBrowser->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); chatBrowser->setStyleSheet("background-image:url(:/guaniu.png);background-position:left bottom;background-attachment:fixed;background-repeat:none;color:#0000FF;font-size:12px;border-radius:3px;padding-bottom:5px;border:1px dashed #008000"); messageSend = new MyTextEdit(this); messageSend->setStyleSheet("color:#008000;border-radius:5px;border:3px solid #FFFFFF;font-size:14px;"); messageSend->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); chessNumber = new QListWidget(this); chessNumber->setStyleSheet("color:#FFD700;font-size:14px;font-weight:normal;"); chessNumber->addItem("5 Chess"); chessNumber->addItem("6 Chess"); chessNumber->addItem("7 Chess"); //chessNumber->currentRow();返回当前的列值几子棋?从0开始默认不选的是-1 点了start按钮把这个值传给服务器 chessNumber->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); startBtn = new QPushButton("Start",this); startBtn->setFont(QFont("Monospace",18,QFont::Bold,false)); startBtn->setStyleSheet("*:enabled{background-color:#FFA500;border-radius:6px;color:#F5F5F5;border:3px solid #FFA500;padding:5px 8px;} *:hover{background-color:#FFD700;border-radius:6px;color:#FFFFFF;border:3px solid #FFD700;padding:5px 8px;} *:!enabled{background-color:#A9A9A9;border-radius:6px;color:#FFFFFF;border:3px solid #A9A9A9;padding:5px 8px;}"); startBtn->setCursor(Qt::PointingHandCursor); timeLabel = new QLabel(this); timeLabel->setText("TIME: 00:00"); timeLabel->setFont(QFont("Monospace",18,QFont::Bold,false)); timeLabel->setStyleSheet("color:#FFD700;border:1px solid #FFFFFF;border-radius:6px;background-color:#FFFFFF"); timeLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); playerLable = new QLabel(this); playerLable->setText("<B style='color:#A9A9A9;font-size:13px;white-space:pre;'> Attention:</B><p style='color:#FFFF00;text-decoration:underline; text-indent:40px;'>who's turn</p>"); playerLable->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); imageLabel = new MyLabel(this); imageLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); QHBoxLayout *list_stBtn = new QHBoxLayout; list_stBtn->addWidget(chessNumber,2); list_stBtn->addWidget(startBtn,1); QVBoxLayout *lefthalf = new QVBoxLayout; lefthalf->addWidget(chatBrowser,3); lefthalf->addWidget(messageSend,1); lefthalf->addLayout(list_stBtn,1); lefthalf->addWidget(timeLabel,1); lefthalf->addWidget(playerLable,1); lefthalf->addWidget(imageLabel,3); //右半边棋盘的类 900个封装成为一个类 初始化为Widget组件 chessArea = new ChessIndividual(this); QHBoxLayout *mainlayout = new QHBoxLayout; mainlayout->addLayout(lefthalf,1); mainlayout->addWidget(chessArea,3); setLayout(mainlayout); .....未完
需要的信号有6个:
1.//发送接收到的信息信号给主线程 void thread_copy_message(QString); 2.//收到了其他玩家开始游戏的邀请 void thread_gameStart_Invite(int,int); 3. //接收到其他玩家同意加入游戏的消息 //现在正式进入游戏 void agree_ToStrat_Game(int); 4.//接收到对方的拒绝信息 void thread_gameDisagree(); 5.//接受到对方的坐标信息 void thread_position(int); 6.//接受到赢家的消息 void thread_winner(int);
#ifndef THREAD_H #define THREAD_H #include <QThread> #include<QTextCodec> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <stdio.h> #include <errno.h> #include <arpa/inet.h>//inet_ntop() #include <unistd.h> class Thread : public QThread { Q_OBJECT public: Thread(); int sockfd;//套节字描述符 //执行客户端连到服务器上的操作返回一个int的sockfd int conn_to_server(); //protected: void run(); signals: //发送接收到的信息信号给主线程 void thread_copy_message(QString); //收到了其他玩家开始游戏的邀请 void thread_gameStart_Invite(int,int); //接收到其他玩家同意加入游戏的消息 //现在正式进入游戏 void agree_ToStrat_Game(int); //接收到对方的拒绝信息 void thread_gameDisagree(); //接受到对方的坐标信息 void thread_position(int); //接受到赢家的消息 void thread_winner(int); }; #endif // THREAD_H
#include "thread.h" #include <QDebug> #define BUF_SIZE 1024 Thread::Thread() { QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); } //客户端链接到服务器上面并返回一个int 的socketfd int Thread::conn_to_server(){ int client_socked_fd = socket(AF_INET,SOCK_STREAM,0); if(client_socked_fd < 0){ fprintf(stderr,"client_socked_fd %s\n",strerror(errno)); exit(1); } //填写主机的信息 struct sockaddr_in addr; memset(&addr,0,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(8080);/********************port *********************/ inet_pton(client_socked_fd,"172.16.3.143",&addr.sin_addr.s_addr); //connect if(::connect(client_socked_fd,(struct sockaddr*)&addr,sizeof(addr)) < 0){ fprintf(stderr,"client_socked_fd %s\n",strerror(errno)); exit(1); } return client_socked_fd; } void Thread::run(){ /*客户端:1发送聊天信息,2实时接受聊天信息 客户端需要分离出来一个子线程,专门用来读取数据, 客户端需要:读取服务器发送到的数据,可以以信号的形式将数据发送给主线程,然后由主线程对相关的组建作出修改!*/ //建立网络链接,拿到套节字描述符 sockfd = conn_to_server(); qDebug()<<"socketfd:"<<sockfd; //接受服务器返回来的数据,并以信号的形式发给主线程,实现相关的功能 int nread; char buffer[BUF_SIZE]; while(1){ memset(buffer,0,sizeof(buffer)); nread = read(sockfd,buffer,sizeof(buffer)); if(nread < 0){ //error fprintf(stderr,"client read from server:%s\b",strerror(errno)); sleep(1); exit(1); }else if(nread == 0){ printf("server connection closed!\n"); exit(1); }else{ //读到了服务器发送回来的数据, //分析 if(strstr(buffer,"#Agree") != NULL){ //对方同意了我的请求 if(strlen(buffer) >= 8){ QString agreeBuf(buffer); int myfd = agreeBuf.remove(0,7).toInt(); qDebug()<<"received myfd:"<<myfd; emit agree_ToStrat_Game(myfd); }else{ emit agree_ToStrat_Game(2); } }else if(strstr(buffer,"#Invite:") != NULL){ //服务器发给了我开始命令 "#Invite:%d,%d" //第一个是对方的fd,第二个是自己的 QString temp(buffer); temp.remove(0,8);//?,? QString teammatefd(temp); teammatefd.remove(1,2); QString myfd(temp); myfd.remove(0,2); //得到对方和自己的fd emit thread_gameStart_Invite(teammatefd.toInt(),myfd.toInt()); }else if(strstr(buffer,"#disAgree") != NULL){ //收到了拒绝的消息 emit thread_gameDisagree(); qDebug()<<"对方拒绝与我玩游戏"; }else if(strstr(buffer,"#Pos:") != NULL){ //收到了坐标信息解析为int型 QString positon(buffer); positon.remove(0,5); emit thread_position(positon.toInt()); //qDebug()<<"收到坐标 x:"<<positon.toInt()/30<<"y:"<<positon.toInt()%30; }else if(strstr(buffer,"#Winner") != NULL){ //服务器发回了赢家的消息 QString winner(buffer); QString x("#"); int index = winner.indexOf(x); winner.remove(index,strlen(winner.toStdString().c_str())); qDebug()<< "winner is:"<<winner.toInt(); emit thread_winner(winner.toInt()); }else{ //服务器发给我的是聊天信息 emit thread_copy_message(buffer); } } } }
定义:
对线程thread的五个信号的槽函数
//接受到了开始的邀请命令,开启对话框 void JoinOrNot(int,int); //接收到了拒绝游戏的命令 void refuse(); //开始游戏 void startGame(int); //收到坐标信号在相应的位置画图 void getPos_and_paintImg(int); //收到赢家的fd void getWinnerInfo(int);
主线程自己的一些槽函数:
//聊天框的处理:向服务器发送聊天信息 void sendMsgToServer(QString); //start按钮的处理:向服务器发送信息#Command: void sendStartMsgToServer(); //刷新计时器 void flushTime(); //向服务器发送坐标信息 void sendMyposition(int);
实现:
所有槽函数的实现:
//向服务器发送文字消息槽函数,meg来自与MyTextEdit的自定义信号 void Widget::sendMsgToServer(QString msg){ //格式化输入,让服务器来判断发送的是聊天信息还是开始游戏的指令 char message[1024] = {0}; //发送的信息message sprintf(message,"#Chat:%s",msg.toStdString().c_str()); ssize_t len = strlen(message); qDebug()<<"message len :"<<len; if(write(th->sockfd,message,len)!=len){ //发送失败 fprintf(stderr,"snedtoserver %s\n",strerror(errno)); exit(1); } } //开始按键的槽函数,向服务器发送命令 void Widget::sendStartMsgToServer(){ char StartMsg[10] = "#Command:"; ssize_t len = strlen(StartMsg); if(write(th->sockfd,StartMsg,len) != len){ fprintf(stderr,"send Start Command: %s",strerror(errno)); } } //是不是开始游戏的槽函数,是否要开始都给对方发送消息 void Widget::JoinOrNot(int parterfd,int myfd){ char Content[256] = {0}; sprintf(Content,"你同意与 玩家%d 玩一局不?",parterfd); int ret = QMessageBox::question(this,"有人邀请你加入游戏",Content,\ QMessageBox::No,QMessageBox::Yes); if(ret == QMessageBox::Yes){ //我同意了对方的邀请,现在给对方发送同意的消息 -->服务器 --> 对方客户端 //我的start按键Enable false 计时器start 棋盘可以点击 //qDebug()<<"I agree the invite"; myfdOnServer = myfd; qDebug()<<"被邀请者:onJoinOrOnt myfdOnServer:"<<myfdOnServer; char AgreeMsg[256] = {0}; sprintf(AgreeMsg,"#Agree:%d",parterfd); ssize_t len = strlen(AgreeMsg); if(write(th->sockfd,AgreeMsg,strlen(AgreeMsg)) != len){ fprintf(stderr,"send AgreeMsg to server:%s\n",strerror(errno)); } }else if(ret == QMessageBox::No){ //我拒绝了对方的邀请,给对方发送拒绝的消息 char disAgreeMsg[256] = {0}; //附带上对方的fd sprintf(disAgreeMsg,"#disAgree:%d",parterfd); ssize_t len = strlen(disAgreeMsg); if(write(th->sockfd,disAgreeMsg,len) != len){ fprintf(stderr,"send disagree command:%s\n",strerror(errno)); exit(1); } } } //刷新时间计时器 void Widget::flushTime(){ sec++; if(sec == 60){ sec=0; min++; } if(min ==60){ min=0; } QString timerstr; timerstr.sprintf("TIME: %02d:%02d",min,sec); timeLabel->setText(timerstr); } //对方同意了我的邀请,开始游戏 void Widget::startGame(int myfd){ //还原时间 min = 0; sec = 0; //时间计时器开启 timer->start(); //count 清理 count = 0; //开始键不可用 startBtn->setEnabled(false); //停止闪烁 killTimer(timerID); //清空上局棋子 if(myfd > 3)myfdOnServer = myfd; for(int i=0;i<900;i++){ chessArea->chessBtn[i/30][i%30]->setIcon(QIcon("")); chessArea->chessBtn[i/30][i%30]->setCheckable(true); //chessArea->chessBtn[i/30][i%30]->setEnabled(true); } } //收到了对方拒绝我邀请的命令 void Widget::refuse(){ QMessageBox::information(this,"对不起!","对方拒绝了你的邀请。",\ QMessageBox::Ok); } //向服务器发送自己的坐标点 void Widget::sendMyposition(int pos){ //在发送端切断已设置过的图标的发送,以免被重新设置ICON 如:对手的棋子又被重设为自己的 if(chessArea->chessBtn[pos/30][pos%30]->isCheckable() == true){ char strpos[10] = {0}; sprintf(strpos,"%d#Pos:%d",myfdOnServer,pos); qDebug()<<"on SendMyPosition:"<<myfdonserver int="" len="strlen(strpos);" if="" myfdonserver="">= 4){ if(write(th->sockfd,strpos,len) != len){ fprintf(stderr,"send positon msg to server:%s\n",strerror(errno)); exit(1); } } } } //收到坐标点 并开始在相应的位置画图 void Widget::getPos_and_paintImg(int pos){ //保存落子上一次的位置 //本次的闪烁,上一次的设置图标 count++; if(count > 1){ killTimer(timerID); } if(count > 1){ int i = lastTimePos/30; int j = lastTimePos%30; if(flag == 0){ //对方的图标 paintingEvent imageLabel->flag = 1; this->update(); playerLable->setStyleSheet("*{background-image:url(:/chess2.png);background-position: left top;background-repeat:none; color:#00ff00}"); chessArea->chessBtn[i][j]->setIcon(QIcon(":/chess2.png")); flag = 1; }else{ //我的图标 paintingEvent imageLabel->flag = 0; this->update(); playerLable->setStyleSheet("*{background-image:url(:/chess4.png);background-position: left top;background-repeat:none; color:#00ff00}"); chessArea->chessBtn[i][j]->setIcon(QIcon(":/chess4.png")); flag = 0; } } //保留本次的位置 lastTimePos = pos; startTimer(500); //设置该按键的可选中属性为false 防止统一个坐标重复设置 chessArea->chessBtn[pos/30][pos%30]->setCheckable(false); } //闪烁 void Widget::timerEvent(QTimerEvent *event){ timerID = event->timerId(); if(blinkflag == 0){ chessArea->chessBtn[lastTimePos/30][lastTimePos%30]\ ->setIcon(QIcon(":/chess1.png")); blinkflag = 1; }else{ if(flag == 0) chessArea->chessBtn[lastTimePos/30][lastTimePos%30]\ ->setIcon(QIcon(":/chess2.png")); if(flag > 0) chessArea->chessBtn[lastTimePos/30][lastTimePos%30]\ ->setIcon(QIcon(":/chess4.png")); blinkflag = 0; } } void Widget::getWinnerInfo(int winnerFd){ //按键变亮 startBtn->setEnabled(true); //停止计时器 timer->stop(); if(winnerFd == myfdOnServer){ //自己赢了游戏 QMessageBox::information(this,"恭喜你!","赢得了本局游戏。",\ QMessageBox::Ok); }else{ if(myfdOnServer == winnerFd-1||myfdOnServer == winnerFd+1){ //自己输了游戏 QMessageBox::information(this,"很遗憾!","你输了,再玩一局吧!",\ QMessageBox::Ok); }else{ char winnerInfo[20]={0}; sprintf(winnerInfo,"本局的赢家是:%d",winnerFd); QMessageBox::information(this,"玩家报告!",winnerInfo,\ QMessageBox::Ok); } } }</myfdonserver>
1,线程Thread的信号和自己的槽函数绑定
//线程Thread的对象 收到消息的信号和槽函数的绑定 th = new Thread;//900:1发送按键组坐标点的信号和槽函数,pos = i*30+j connect(chessArea->BtnGroup,SIGNAL(buttonPressed(int)),this,SLOT(sendMyposition(int))); //客户端接收到的(read())从服务器发的【文字】消息,并把它追加到chatVrowser中 connect(th,SIGNAL(thread_copy_message(QString)),chatBrowser,SLOT(append(QString))); //客户端收到从服务器发过来的开始游戏的邀请命令 connect(th,SIGNAL(thread_gameStart_Invite(int,int)),this,SLOT(JoinOrNot(int,int))); //客户端收到对方发过来的同意游戏的消息 开始游戏 connect(th,SIGNAL(agree_ToStrat_Game(int)),this,SLOT(startGame(int))); //客户端接收到对方发来的拒绝游戏的消息 弹出拒绝消息 connect(th,SIGNAL(thread_gameDisagree()),this,SLOT(refuse())); //接受到位置的坐标信息并开始画图的信号函数和槽函数绑定 connect(th,SIGNAL(thread_position(int)),this,SLOT(getPos_and_paintImg(int))); //接受到赢家的消息 connect(th,SIGNAL(thread_winner(int)),this,SLOT(getWinnerInfo(int))); th->start();
2.自己的信号和槽函数绑定
connect(messageSend,SIGNAL(sendChatMsg(QString)),this,SLOT(sendMsgToServer(QString))); //开始按键的信号和槽函数 connect(startBtn,SIGNAL(clicked()),this,SLOT(sendStartMsgToServer())); //900:1发送按键组坐标点的信号和槽函数,pos = i*30+j connect(chessArea->BtnGroup,SIGNAL(buttonPressed(int)),this,SLOT(sendMyposition(int))); //计时器的初始化 一秒为最小计时单位 timer = new QTimer(this); timer->setInterval(1000); //刷新时间 设置timelabel上面的时间 connect(timer,SIGNAL(timeout()),this,SLOT(flushTime()));