6.5 绘制事件
1> 对于QT窗口而言,最先接触的是绘制事件,整个窗口的内容都是有绘制事件绘制出来的
2> 触发条件:当窗口第一次展示出来、由最小化重新展示出来、窗口最大化、由最大化转变正常、改变窗口大小、使用updata函数进行更新界面时
3> 在绘制事件处理函数中,可以使用画家类对界面进行相关绘制工作
4> 实现实例
一、回顾TCP网络通信步骤
二、QT中的TCP网络通信
2.1 服务器端(QTcpServer)
1> 使用QTcpServer类实例化一个对象,就得到了一个服务器端
2> 调用该类对象的成员函数 listen 将服务器启动监听,该函数会进行绑定ip和端口号
ip地址可以指定也可以由系统自动绑定,端口号也可以自己指定和由系统自动指定
3> 当有客户端发来连接请求后,该服务器就会自动发射一个newConnection的信号
我们可以将该信号绑定到自定义的槽函数中完成相关逻辑
4> 可以使用类中的成员函数 nextPenddingConnection 可以获取最新连接的客户端套接字
5> 可以使用该客户端套接字进行数据收发
read、readLine、readAll读取数据
write发送数据
6> 当服务器收到客户端的消息后,该服务器会自动发射一个readyRead的信号
可以将该信号连接到对应的槽函数中,处理客户端发来的消息
7> 调用成员函数close关闭监听
2.2 客户端(QTcpSocket)
1> 使用该类实例化一个对象,就创建了一个客户端
2> 使用该类对象的成员函数 connectToHost 向服务器发送连接请求
如果连接服务器成功,那么该客户端套接字就会自动发射一个 connected 的信号
可以将该信号连接到自定义的槽函数中处理相关逻辑
3> 可以使用该客户端套接字进行数据收发
read、readLine、readAll读取数据
write发送数据
4> 如果客户端收到服务器发来的消息后,该客户端就会自动发射一个readyRead的信号
可以将该信号连接到对应的槽函数中,处理客户端发来的消息
5> 调用成员函数 disconnectFromHost 断开跟服务器的连接
作业
1> 使用绘制事件完成钟表的绘制
2> 将网络聊天室自己实现一遍
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(500,500);
this->setFixedSize(500,500);
this->setStyleSheet("background-color:pink;");
pix = new QPixmap(this->size()); //实例化一个膜大小跟当前界面一致
//启动一个计时器
tid = this->startTimer(1000);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter p2(this);
//2、将pix绘制到界面上
p2.drawPixmap(QPoint(0,0), *pix);
//实例化一个画家,用于画背景
QPainter painter(this);
//准备字体
QFont font;
font.setFamily("华文行楷"); //设置字体族
font.setStyle(QFont::StyleItalic); //设置字体倾斜
font.setPointSize(40);
painter.setFont(font);
//准备画笔
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setColor(QColor("yellow"));
pen.setWidth(5);
painter.setPen(pen);
painter.drawText(this->rect(), //绘制的区域矩形框
Qt::AlignCenter, //绘制的对齐方式
"五粮液"); //绘制的文本内容
painter.translate(250,250);
painter.drawEllipse(QPoint(0,0),200,200);
for(int i=1;i<=12;i++)
{
painter.drawLine(QPoint(0,190),QPoint(0,200));
painter.rotate(30);
}
for(int i=1;i<=60;i++)
{
painter.drawLine(QPoint(0,195),QPoint(0,200));
painter.rotate(6);
}
}
void Widget::timerEvent(QTimerEvent *event)
{
if(event->timerId()==tid)
{
pix->fill(Qt::darkBlue);
//获取系统的时间
QTime sysTime = QTime::currentTime();
//将QTime类对象转变成字符串
//准备秒钟画笔
QPainter p1(pix);
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setColor(QColor("blue"));
pen.setWidth(2);
p1.setPen(pen);
p1.translate(250,250);
p1.rotate(sysTime.second()*6+180);
p1.drawLine(QPoint(0,0),QPoint(0,200));
pen.setColor(QColor("green"));
pen.setWidth(4);
p1.setPen(pen);
p1.rotate(sysTime.minute()*6-sysTime.second()*6);
p1.drawLine(QPoint(0,0),QPoint(0,150));
pen.setColor(QColor("red"));
pen.setWidth(6);
p1.setPen(pen);
p1.rotate(sysTime.hour()*30-sysTime.minute()*6);
p1.drawLine(QPoint(0,0),QPoint(0,100));
//3、更新界面内容
this->update();
qDebug("发送");
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QPainter>
#include<QTimer>
#include<QDebug>
#include<QTime>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
int tid;
void timerEvent(QTimerEvent *event) override;
void paintEvent(QPaintEvent *event) override;
QPixmap *pix;
};
#endif // WIDGET_H
效果图: