1.思维导图
2.服务器
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//给服务器指针实例化空间
server = new QTcpServer(this);
}
Widget::~Widget()
{
delete ui;
}
//启动服务器按钮对应的槽函数
void Widget::on_startbtn_clicked()
{
//获取ui的端口号
quint16 port = ui->portedt->text().toUInt();
//将服务器设置监听状态
//函数原型:bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
//功能:将服务器设置成监听状态
//参数1:连接的主机地址,QHostAddress::Any,允许任意主机进行连接,当然,也可以指定主机号进行连接
//参数2:连接进来所需端口号,0表示任意端口号进行访问,也可以指定端口号进行访问服务器
//返回值:成功返回true,失败返回false
if (server->listen(QHostAddress::Any, port))
{
QMessageBox::information(this, "", "服务器启动成功");
}else
{
QMessageBox::information(this, "", "服务器启动失败");
}
//此时服务器进入监听,如果客户端发来连接请求,那么服务器自动发射newConnection信号
//我们可以将该信号连接到自定义的槽函数处理新连接的套接字
connect(server, &QTcpServer::newConnection, this, &Widget::newconnect_slot);
}
//处理newConnection信号的槽函数的实现
void Widget::newconnect_slot()
{
qDebug() << "有新用户连接";
//获取新连接的套接字
//函数原型:[virtual] QTcpSocket *QTcpServer::nextPendingConnection()
//功能:获取最新一次连接的客户端套接字
//参数:无
//返回值:最新连接客户端的套接字
QTcpSocket *s = server->nextPendingConnection();
//将新的套接字放入到客户端链表中
socketList.push_back(s);
//此时,客户端和服务器已经建立连接,那么,就可以进行数据的收发了
//如果客户端有数据发送给服务器,那么客户端就会自动触发一个readyRead的信号
//我们将该信号连接到自定义的槽函数中,处理相关逻辑
connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}
//自定义处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
//将无效的客户端移除出链表
for(int i=0; i<socketList.size(); i++)
{
//对第i个客户端的状态进行判断,如果是无连接的 状态,则进行移除
//QAbstractSocket::SocketState QAbstractSocket::state() const
//功能:查看客户端的状态
//参数:无
//返回值:当前客户端的状态
if(socketList.at(i)->state() == 0)
{
//如果当前状态无连接的,则进行移除
socketList.removeAt(i);
}
}
//将所有有效的客户端进行遍历,查看是哪个客户端中有数据待读
for(int i=0; i<socketList.size(); i++)
{
//判断当前客户端是否有待读数据
//qint64 QAbstractSocket::bytesAvailable() const
//功能:返回待读数据的字节数
//参数:无
if(socketList.at(i)->bytesAvailable() != 0)
{
//读取数据
//QByteArray QIODevice::readAll()
//功能:读取出当前客户端中所有信息
//参数:无
//返回值:字节数组
QByteArray msg = socketList.at(i)->readAll();
//将读取的数据展示到自身的ui界面
ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
//将该消息广播给所有客户端
for(int j=0; j<socketList.size(); j++)
{
socketList.at(j)->write(msg);
}
}
}
3.时钟
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// this->setFixedSize(width, height);
timer = new QTimer;
timer->start(1000);
connect(timer, &QTimer::timeout, [&](){
count++;
update();
});
//获取系统时间
QString t = QTime::currentTime().toString("h:m:s ap");
QStringList list1 = t.split(" ");
QStringList list2 = list1[0].split(":");
for (int i=0; i<list2.size(); i++)
{
qDebug() << list2.at(i);
}
hour = list2[0].toUInt();
minute = list2[1].toUInt();
second = list2[2].toUInt();
qDebug() << "hour:" << hour << "minute:" << minute << "second" << second;
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
//定义画家类绘制圆
QPainter p(this);
QPen pen(QColor("purple"));
pen.setWidth(3);
QBrush b("pink");
p.setPen(pen);
p.setBrush(b);
p.translate(this->width()/2, this->height()/2);
p.drawEllipse(QPoint(0, 0), 200, 200);
//使用画家类绘制刻度
pen.setColor(QColor("black"));
p.setPen(pen);
for (int i=0; i<60; i++)
{
p.rotate(6);
p.drawLine(QPoint(200, 0), QPoint(195, 0));
}
pen.setWidth(5);
p.setPen(pen);
for (int i=0; i<12; i++)
{
p.drawLine(QPoint(200, 0), QPoint(190, 0));
p.rotate(30);
p.drawText(QPoint(0, -170), QString("%1").arg(i+1));
}
//制作时针
pen.setWidth(10);
pen.setColor(QColor("red"));
p.setPen(pen);
p.rotate(hour*30+6*second/60/12+30*minute/60+6*count/60/12);
p.drawLine(QPoint(0, -50), QPoint(0, 5));
//制作分针
QPainter p1(this);
p1.translate(this->width()/2, this->height()/2);
pen.setWidth(6);
pen.setColor(QColor("blue"));
p1.setPen(pen);
p1.rotate(6*count/60+minute*6+6*second/60);
p1.drawLine(QPoint(0, -80), QPoint(0, 8));
//制作秒针
QPainter p2(this);
p2.translate(this->width()/2, this->height()/2);
pen.setWidth(3);
pen.setColor(QColor("green"));
p2.setPen(pen);
p2.rotate(6*count+second*6);
p2.drawLine(QPoint(0, -120), QPoint(0, 12));
}