#include "widget.h"
#include "ui_widget.h"
#include <QTextCodec>
#include <QMessageBox>
#include <QDataStream>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
/* 支持中文显示 */
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
/* 创建 socket */
tcpClient = new QTcpSocket(this);
/* 如果连接成功, 触发 serverConnect 函数 */
connect(tcpClient, SIGNAL(connected()), this, SLOT(serverConnect()));
connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readData()));
/* 连接按键 */
connectButn = new QPushButton(tr("连接"));
connectButn->setEnabled(false);
/* 取消按键 */
cancleButn = new QPushButton(tr("取消"));
cancleButn->setEnabled(false);
ipLabel = new QLabel(tr("服务器"));
hostLineEdit = new QLineEdit;
portLabel = new QLabel(tr("端口号"));
portLineEdit = new QLineEdit;
tempLabel = new QLabel(tr("温 度"));
tempSpinBox = new QSpinBox;
tempSpinBox->setRange(-20, 50);
tempFreshButn = new QPushButton(tr("刷新"));
tempSetButn = new QPushButton(tr("设置"));
wetLabel = new QLabel(tr("湿 度"));
wetSpinBox = new QSpinBox;
wetSpinBox->setRange(0, 100);
wetFreshButn = new QPushButton(tr("刷新"));;
wetSetButn = new QPushButton(tr("设置"));
bright = new QLabel(tr("亮 度"));
spinbox = new QSpinBox;
slider = new QSlider(Qt::Horizontal);
spinbox->setRange(0, 100);
spinbox->setValue(50);
slider->setRange(1, 100);
slider->setValue(50);
bedLightBtn = new QPushButton(tr("打 开"));
bedLightLabel = new QLabel(tr(" bedroom"));
bedBool = false;
mainLightBtn = new QPushButton(tr("打 开"));
mainLightLabel = new QLabel(tr(" main"));
mainBool = false;
kitchLightBtn = new QPushButton(tr("打 开"));
kitchLightLabel = new QLabel(tr(" kitch"));
kitchBool = false;
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sendData(int)));
connect(slider, SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
/* IP 编辑框和端口编辑框, 触发的槽函数 */
connect(hostLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(hostEdit(const QString &)));
connect(portLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(hostEdit(const QString &)));
/* 连接按钮与取消按钮连接的槽函数 */
connect(connectButn, SIGNAL(clicked()), this, SLOT(clickOK()));
connect(cancleButn, SIGNAL(clicked()), this, SLOT(clickCancl()));
connect(bedLightBtn, SIGNAL(clicked()), this, SLOT(bedclick()));
connect(mainLightBtn, SIGNAL(clicked()), this, SLOT(mainclick()));
connect(kitchLightBtn,SIGNAL(clicked()), this, SLOT(kitchclick()));
/*----------------------- 控件布局 -------------------------*/
hbox1 = new QHBoxLayout;
hbox1->addWidget(ipLabel);
hbox1->addWidget(hostLineEdit);
hbox1->addWidget(connectButn);
hbox2 = new QHBoxLayout;
hbox2->addWidget(portLabel);
hbox2->addWidget(portLineEdit);
hbox2->addWidget(cancleButn);
hbox3 = new QHBoxLayout;
hbox3->addWidget(tempLabel);
hbox3->addWidget(tempSpinBox);
hbox3->addWidget(tempFreshButn);
hbox3->addWidget(tempSetButn);
hbox4 = new QHBoxLayout;
hbox4->addWidget(wetLabel);
hbox4->addWidget(wetSpinBox);
hbox4->addWidget(wetFreshButn);
hbox4->addWidget(wetSetButn);
hbox5 = new QHBoxLayout;
hbox5->addWidget(bright);
hbox5->addWidget(slider);
hbox5->addWidget(spinbox);
grid = new QGridLayout;
grid->addWidget(bedLightBtn, 0, 0);
grid->addWidget(mainLightBtn, 0, 1);
grid->addWidget(kitchLightBtn, 0, 2);
grid->addWidget(bedLightLabel, 1, 0);
grid->addWidget(mainLightLabel, 1, 1);
grid->addWidget(kitchLightLabel,1, 2);
vbox = new QVBoxLayout;
vbox->addLayout(hbox1);
vbox->addLayout(hbox2);
vbox->addLayout(hbox3);
vbox->addLayout(hbox4);
vbox->addLayout(hbox5);
vbox->addLayout(grid);
setLayout(vbox);
QWidget::setMaximumWidth(268);
/* 设置固定高度, sizeHint 返回的是最合适的大小 */
QWidget::setFixedHeight(sizeHint().height());
/* 设置固定宽度, sizeHint 返回的是最合适的大小 */
//QWidget::setFixedWidth(sizeHint().width());
ui->setupUi(this);
}
/* IP 编辑框和端口编辑框槽函数 */
void Widget::hostEdit(const QString &str)
{
/* 只有当用户输入了 IP 端口, 连接按键才可以使用 */
if ( hostLineEdit->text().isEmpty() || portLineEdit->text().isEmpty() )
{
connectButn->setEnabled(false);
}
else
{
connectButn->setEnabled(true);
}
}
/* 连接按键槽函数 */
void Widget::clickOK()
{
/* 点击连接之后, 按键处于不可用状态 */
connectButn->setEnabled(false);
/* 不可修改服务器 IP 地址 */
hostLineEdit->setEnabled(false);
/* 不可修改服务器端口 */
portLineEdit->setEnabled(false);
/* 取消按钮可用 */
cancleButn->setEnabled(true);
/* 连接服务器 */
tcpClient->connectToHost(hostLineEdit->text(), portLineEdit->text().toInt());
}
/* 取消按钮 */
void Widget::clickCancl()
{
/* 连接按钮可用 */
connectButn->setEnabled(true);
/* IP 编辑框可用 */
hostLineEdit->setEnabled(true);
/* 服务器端口编辑框可用 */
portLineEdit->setEnabled(true);
/* 取消按钮不可用 */
cancleButn->setEnabled(false);
tcpClient->close();
QMessageBox::about(NULL, "消息来自客户端", "断开服务器连接");
}
void Widget::serverConnect()
{
if ( tcpClient->state() == QAbstractSocket::ConnectedState )
{
QMessageBox::about(NULL, "消息来自客户端", "连接服务器成功");
}
}
Widget::~Widget()
{
tcpClient->deleteLater();
if (tcpClient != NULL)
{
delete tcpClient;
tcpClient = NULL;
}
delete ui;
}
void Widget::sendData(int value)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
//out.setVersion(QDataStream::Qt_4_7);
out.setVersion(QDataStream::Qt_4_5); /* 开发板使用的版本 */
out << (quint16)0 << value;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
tcpClient->write(block);
}
void Widget::readData()
{
}
void Widget::bedclick()
{
if ( bedBool )
{
bedLightBtn->setText(tr("打 开"));
bedBool = false;
}
else
{
bedLightBtn->setText(tr("关 闭"));
bedBool = true;
}
}
void Widget::mainclick()
{
if ( mainBool )
{
mainLightBtn->setText(tr("打 开"));
mainBool = false;
}
else
{
mainLightBtn->setText(tr("关 闭"));
mainBool = true;
}
}
void Widget::kitchclick()
{
if ( kitchBool )
{
kitchLightBtn->setText(tr("打 开"));
kitchBool = false;
}
else
{
kitchLightBtn->setText(tr("关 闭"));
kitchBool = true;
}
}
服务端
widget.h
#ifndef WIDGET_H#define WIDGET_H
#include <QWidget>
#include <QtNetWork>
/* 4.5 版本的 QT 头文件 - ARM 开发板使用的 Qt 版本
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QTcpServer>
*/
#include <QFile>
#include <QFileDialog>
#include <QString>
#include <QByteArray>
#include <QLabel>
#include <QSpinBox>
#include <QHBoxLayout>
namespace Ui
{
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
private :
QTcpServer *tcpServer;
QTcpSocket *clientSocket;
QLabel *bright;
QSpinBox *spinbox;
QHBoxLayout *hbox;
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
private slots :
void newConnect();
void readMsg();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"#include "ui_widget.h"
#include <QMessageBox>
#include <QTextCodec>
#include <QDataStream>
#include <QHBoxLayout>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
/* 支持中文显示 */
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
bright = new QLabel(tr("亮度值"));
spinbox = new QSpinBox;
spinbox->setRange(0, 100);
spinbox->setValue(0);
hbox = new QHBoxLayout;
hbox->addWidget(bright);
hbox->addWidget(spinbox);
setLayout(hbox);
/* 设置固定高度, sizeHint 返回的是最合适的大小 */
QWidget::setFixedHeight(sizeHint().height());
/* 设置固定宽度, sizeHint 返回的是最合适的大小 */
QWidget::setFixedWidth(sizeHint().width());
tcpServer = new QTcpServer(this);
if ( !tcpServer->listen(QHostAddress::Any, 6666) )
{
QMessageBox::about(NULL, "监听失败", tcpServer->errorString());
close();
}
/* 有客户端连接, 发送信号触发槽函数 */
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnect()));
ui->setupUi(this);
}
Widget::~Widget()
{
delete tcpServer;
delete ui;
}
/* 有客户端连接时 */
void Widget::newConnect()
{
QMessageBox::about(NULL, "服务器消息", "有新的客户端连接");
/* 获取建立连接的套接字 */
clientSocket = tcpServer->nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readMsg()));
/* 关联槽函数, 当断开连接时, 会自动删除该套接字 */
connect(clientSocket, SIGNAL(disconnected()), clientSocket, SLOT(deleteLater()));
}
void Widget::readMsg()
{
int data;
QDataStream in(clientSocket);
in.setVersion(QDataStream::Qt_4_7);
quint16 blockSize = 0;
if ( blockSize == 0 )
{
if ( clientSocket->bytesAvailable() < (int)sizeof(quint16) )
{
return;
}
in >> blockSize;
}
in >> data;
spinbox->setValue(data);
}