Qt学习 (三) : 一个简陋的调查问卷

学习一点TCP网络协议的知识,利用Qt做一次调查问卷,客户端与服务器端如下:

服务器:    

客户端:    

客户端:

首先在创建的tcpclient工程下的tcpclient.pro中加入

QT += network

然后编写tcpclient.h

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QDialog>
#include <QListWidget>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QHostAddress>
#include <QTcpSocket>
#include <QButtonGroup>
#include <QLineEdit>

class TcpClient : public QDialog
{
    Q_OBJECT

public:
    TcpClient(QWidget *parent = 0,Qt::WindowFlags f=0);
    ~TcpClient();
private:

    QString username1;

    QPushButton *saveBtn;
    QPushButton *submitBtn;


    QLabel *title;

    QLineEdit *lineedit1;
    QLabel *username;
    QPushButton *yesbutton;


    QLabel *question1;
    QLabel *question2;
    QLabel *question3;
    QLabel *question31;
    QLabel *question32;
    QLabel *question33;
    QLabel *question34;

    QButtonGroup *answer1;
    QButtonGroup *answer2;
    QButtonGroup *answer3A;
    QButtonGroup *answer3B;
    QButtonGroup *answer3C;
    QButtonGroup *answer3D;

    QCheckBox *answer11;
    QCheckBox *answer12;
    QCheckBox *answer13;

    QCheckBox *answer21;
    QCheckBox *answer22;

    QCheckBox *answer311;
    QCheckBox *answer312;

    QCheckBox *answer321;
    QCheckBox *answer322;

    QCheckBox *answer331;
    QCheckBox *answer332;

    QCheckBox *answer341;
    QCheckBox *answer342;

    QGridLayout *mainLayout;

    bool savestatus;
    bool submitstatus;

    int port;

    QHostAddress *serverIP;

    QTcpSocket *tcpSocket;

public slots:
    QString slotSave();
    void slotConnected();

    void getname();

    void slotSaveBox();
    void dataReceived();
    void slotSubmit();
    QString slotAnswer1();
    QString slotAnswer2();
};

#endif // TCPCLIENT_H

 

tcpclient.cpp

#include "tcpclient.h"
#include <QMessageBox>
#include <QHostInfo>

TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)
    : QDialog(parent,f)
{
    setWindowTitle(tr("问卷调查"));

    title = new QLabel(tr("TMD疼痛筛查表"));
    QPalette pe;
    pe.setColor(QPalette::WindowText,Qt::red);
    title->setPalette(pe);

    lineedit1 = new QLineEdit(this);
    username = new QLabel(tr("用户名"));
    yesbutton = new QPushButton(tr("确认"));

    saveBtn = new QPushButton(tr("保存"));
    savestatus = false;
    saveBtn->setEnabled(false);
    submitBtn = new QPushButton(tr("提交"));
    submitstatus = false;
    submitBtn->setEnabled(false);

    question1 = new QLabel(tr("1.最近30天内,任一侧的下颌或太阳穴部位的疼痛持续了多久?"));
    answer11 = new QCheckBox(tr("a.没有疼痛"));
    answer12 = new QCheckBox(tr("b.断断续续"));
    answer13 = new QCheckBox(tr("c.一直有疼痛"));
    answer1 = new QButtonGroup(this);
    answer1->addButton(answer11);
    answer1->addButton(answer12);
    answer1->addButton(answer13);

    question2 = new QLabel(tr("2.最近30天内,醒来时下颌是否感觉疼痛或者僵硬?"));
    answer21 = new QCheckBox(tr("a.是"));
    answer22 = new QCheckBox(tr("b.否"));
    answer2 = new QButtonGroup(this);
    answer2->addButton(answer21);
    answer2->addButton(answer22);

   // question31


    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(title,0,1,1,1,Qt::AlignCenter);

    mainLayout->addWidget(username,2,0,1,1);
    mainLayout->addWidget(lineedit1,2,2,1,1);
    mainLayout->addWidget(yesbutton,2,3,1,1);

    mainLayout->addWidget(submitBtn,2,4,1,1);

    mainLayout->addWidget(question1,3,0,1,0);
    mainLayout->addWidget(answer11,4,0,1,1);
    mainLayout->addWidget(answer12,5,0,1,1);
    mainLayout->addWidget(answer13,6,0,1,1);

    mainLayout->addWidget(question2,8,0,1,0);
    mainLayout->addWidget(answer21,9,0,1,1);
    mainLayout->addWidget(answer22,10,0,1,1);



    mainLayout->addWidget(saveBtn,20,1,1,1,Qt::AlignCenter);



    port = 8010;

    serverIP =new QHostAddress();
    QString ip = "127.0.0.1";
    serverIP->setAddress(ip);

    tcpSocket = new QTcpSocket(this);
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));
    tcpSocket->connectToHost(*serverIP,port);

    connect(saveBtn,SIGNAL(clicked(bool)),this,SLOT(slotSave()));
    connect(saveBtn,SIGNAL(clicked(bool)),this,SLOT(slotSaveBox()));
    connect(submitBtn,SIGNAL(clicked(bool)),this,SLOT(slotSubmit()));

//问题1
    connect(answer11,SIGNAL(clicked(bool)),this,SLOT(slotAnswer1()));
    connect(answer12,SIGNAL(clicked(bool)),this,SLOT(slotAnswer1()));
    connect(answer13,SIGNAL(clicked(bool)),this,SLOT(slotAnswer1()));

//问题2
    connect(answer21,SIGNAL(clicked(bool)),this,SLOT(slotAnswer2()));
    connect(answer22,SIGNAL(clicked(bool)),this,SLOT(slotAnswer2()));

    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived()));

    connect(yesbutton,SIGNAL(clicked(bool)),this,SLOT(getname()));
}

void TcpClient::slotConnected()
{
    savestatus = true;
    saveBtn->setEnabled(savestatus);
}

void TcpClient::getname()
{
  username1 = lineedit1->text();

}


QString TcpClient::slotAnswer1()
{
    QString msg1;
    if(answer11->isChecked()==true)
    {
       msg1 = "a" ;
       return msg1;
    }
    if(answer12->isChecked()==true)
    {
       msg1 = "b" ;
       return msg1;
    }
    if(answer13->isChecked()==true)
    {
       msg1 = "c" ;
       return msg1;
    }
    else
    {
        msg1 = "quetion1 has no answer";
        return msg1;
    }
}

QString TcpClient::slotAnswer2()
{
    QString msg2;
    if(answer21->isChecked()==true)
    {
       msg2 = "a" ;
       return msg2;
    }
    if(answer22->isChecked()==true)
    {
       msg2 = "b" ;
       return msg2;
    }

    else
    {
        msg2 = "question2 has no answer";
        return msg2;
    }
}

QString TcpClient::slotSave()
{
    submitstatus = true;
    submitBtn->setEnabled(savestatus);
    QString msgsave;
    msgsave =username1+":\nThe answer1 is:  "+ slotAnswer1()+ "\nThe answer2 is:  "+ slotAnswer2()+"\n end";    //给服务器发送信息
    return msgsave;
}

void TcpClient::slotSubmit()
{
    QString msgsubmit = slotSave();
    submitstatus = false;
    submitBtn->setEnabled(submitstatus);
    tcpSocket->write(msgsubmit.toLatin1(),msgsubmit.length());

}

void TcpClient::slotSaveBox()
{
    QMessageBox::information(NULL, "Title", "保存成功",  QMessageBox::Ok);                        //返回消息框
}

void TcpClient::dataReceived()
{
    while(tcpSocket->bytesAvailable()>0)
    {
        QByteArray datagram;
        datagram.resize(tcpSocket->bytesAvailable());
        tcpSocket->read(datagram.data(),datagram.size());
        QString msg=datagram.data();
        if(msg.left(datagram.size())=="OK"+0)
        {
                QMessageBox::information(NULL, "Title", "提交成功",  QMessageBox::Ok);
        }
    }
}

TcpClient::~TcpClient()
{

}

服务器:

同样地需要在tcpserver.pro中加入 QT = +network 语句

tcpclientsocket.h

#ifndef TCPCLIENTSOCKET_H
#define TCPCLIENTSOCKET_H

#include <QTcpSocket>
#include <QObject>

class tcpclientsocket : public QTcpSocket
{

    Q_OBJECT
public:
    tcpclientsocket(QObject *parent=0);
signals:
    void updataClients(QString,int);

protected slots:
    void dataReceived();
};

#endif // TCPCLIENTSOCKET_H

tcpclientsocket.cpp

#include "tcpclientsocket.h"

tcpclientsocket::tcpclientsocket(QObject *parent)
{
    connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
}

void tcpclientsocket::dataReceived()
{
    while(bytesAvailable()>0)
    {
        int length = bytesAvailable();
        char buf[1024];
        read(buf,length);
        QString msg=buf;
        emit updataClients(msg,length);                //发送信号
    }
}

server.h

#ifndef SERVER_H
#define SERVER_H

#include "tcpclientsocket.h"

#include <QTcpServer>
#include <QObject>

class Server : public QTcpServer
{
    Q_OBJECT
public:
    Server(QObject *parent=0,int port=0);
    QList<tcpclientsocket*>tcpClientSocketList;
signals:
    void updataServer(QString,int);
public slots:
    void updataClients(QString,int);

protected:
    void incomingConnection(int socketDescriptor);

};

#endif // SERVER_H

server.cpp

(这里写得很不好,但因为对网络TCP协议理解尚且较浅,就以实现目的为先了。)

#include "server.h"

Server::Server(QObject *parent,int port):QTcpServer(parent)
{
    listen(QHostAddress::Any,port);
}

void Server::incomingConnection(int socketDescriptor)
{
    tcpclientsocket *tcpClientSocket = new tcpclientsocket(this);
    connect(tcpClientSocket,SIGNAL(updataClients(QString,int)),
            this,SLOT(updataClients(QString,int)));
    tcpClientSocket->setSocketDescriptor(socketDescriptor);
    tcpClientSocketList.append(tcpClientSocket);

}


void Server::updataClients(QString msg, int length)
{
        emit updataServer(msg,length);
        QString msg1 = "OK"+0;                                    //发送OK+0,我默认了另一个服务器是第0个,这也是这里最大的问题;因为利用                                                                   //循化后程序无法达到理想状况。                                              QTcpSocket *item = tcpClientSocketList.at(0);
        item->write(msg1.toLatin1(),msg1.length());
}

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include "server.h"

#include <QDialog>
#include <QListWidget>
#include <QPushButton>
#include <QGridLayout>

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    QListWidget *ContentWidget;
    QPushButton *CreateBtn;
    QGridLayout *mainLayout;

    int port;
    Server *server;

    QTcpSocket *tcpsocketreturn1;

public slots:
    void slotCreateServer();
    void updateServer(QString,int);
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"


#include<QtDebug>

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    port=8010;

    setWindowTitle(tr("服务器显示"));
    ContentWidget = new QListWidget;
    CreateBtn = new QPushButton("创建");

    mainLayout = new QGridLayout(this);
    mainLayout->addWidget(ContentWidget,0,0,1,2);
    mainLayout->addWidget(CreateBtn,2,0,1,2);

    connect(CreateBtn,SIGNAL(clicked(bool)),this,SLOT(slotCreateServer()));
}

void Dialog::slotCreateServer()
{
    qDebug() <<"created";
    server = new Server(this,port);
    connect(server,SIGNAL(updataServer(QString,int)),this,SLOT(updateServer(QString,int)));
    CreateBtn->setEnabled(false);
}


void Dialog::updateServer(QString msg, int length)
{
    ContentWidget->addItem(msg.left(length));
    ContentWidget->addItem("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

}


Dialog::~Dialog()
{

}

然后先运行服务器程序,点击创建后即可建立连接(只有建立连接,客户端才可以将答案保存到变量中):

在填写好用户名后,点击确认并开始选择答案。选择好之后,点击保存,此时提交通道打开(即可以点击提交):

然后点击提交按钮,即可将数据发送到服务器端:

此时服务器端会发送一个“OK”+0到客户端,客户端响应后弹出“提交成功”的消息框:

这样就完成了一个简陋的调查问卷!

本次用Qt,我又有了2点对Qt的新的认识

1.Qt中的信号不一定非要是控件(如按钮按下)产生,也可以是人为发出,提交了程序的灵活性。而且在同一工程中,信号名字在不同文件中是可以相同的,且可以互相连接,加深了我对信号与槽的理解(即这一机制是由对象和函数组成共同组成的的)

2.Qt中槽函数和其他函数有许多相似性,也可以返回值(答案的返回我是这么实现的),只是它接收信号之后执行而已(槽函数又像是满足一定条件时被调用的函数,与之前学习的单片机中的中断函数很像,不过是“激活”条件不一样)。

猜你喜欢

转载自blog.csdn.net/bingkuoluo/article/details/80606810