QT作业3
1> 使用绘制事件完成钟表的绘制
代码:
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<iostream>
#include<QDebug>
#include<QIcon>
#include<QPushButton>
#include<QLabel>
#include<QMovie>
#include<QLineEdit>
#include<QMessageBox>
#include<QTimer>
#include<QTime>
#include<QString>
#include<QTimerEvent>
#include<QPushButton>
#include<QDateTime>
#include<QPen>
#include<QPainter>
#include <QPaintEvent>
#include<QPixmap>
#include<QColor>
#include<QColorDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent *event) override;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
源文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//每秒刷新
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&Widget::update));
timer->start(1000);
setWindowTitle(tr("Clock"));
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40) // 设置时针长度
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70) // 设置分针长度
};
static const QPoint secondHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -90) // 设置秒针长度
};
//设置指针颜色
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
QColor secondColor(Qt::red);
int side = qMin(width(), height()); // 获取窗口的较小边长度,用于后续绘制时的缩放
QTime time = QTime::currentTime(); // 获取当前时间
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 设置抗锯齿渲染提示,提高绘制质量
painter.translate(width() / 2, height() / 2); // 将坐标原点移动到窗口中心
painter.scale(side / 200.0, side / 200.0); // 根据窗口大小进行缩放,确保时钟的合适显示比例
// 绘制时针刻度
painter.setPen(Qt::NoPen); // 设置画笔无边框
painter.setBrush(hourColor);
painter.save(); // 保存当前QPainter状态
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); // 根据当前时数和分钟计算旋转角度
painter.drawConvexPolygon(hourHand, 3); // 绘制时针
painter.restore(); // 恢复QPainter状态到之前保存的状态
painter.setPen(hourColor);
for (int i = 0; i < 12; ++i)
{
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
// 绘制分针和分钟刻度
painter.setPen(Qt::NoPen); // 设置画笔无边框
painter.setBrush(minuteColor);
painter.save(); // 保存当前QPainter状态
painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); // 根据当前分钟和秒数计算旋转角度
painter.drawConvexPolygon(minuteHand, 3); // 绘制分针
painter.restore(); // 恢复QPainter状态到之前保存的状态
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j)
{
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
// 绘制秒针
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
painter.rotate(6.0 * time.second()); // 根据当前秒数计算旋转角度
painter.drawConvexPolygon(secondHand, 3); // 绘制秒针
painter.restore();
}
运行结果:
2> 将网络聊天室自己实现一遍
代码:
服务器:
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpServer> //TCP服务器
#include <QTcpSocket> //TCP客户端
#include <QList> //链表
#include <QMessageBox>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void newConnection_slot();
void readyRead_slot();
private:
Ui::Widget *ui;
QTcpServer *server;
QList<QTcpSocket *> socketList;
};
#endif // WIDGET_H
源文件
#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_pushButton_clicked()
{
if(ui->pushButton->text() == "启动")
{
//启动服务器
//获取端口号
quint16 port = ui->lineEdit->text().toUInt();
//启动监听: bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
//参数1:监听的IP地址,Any为监听所有端口号
//参数2,监听的端口号,不指定则随机
//返回值:成功返回真,失败返回假
if(!server->listen(QHostAddress::Any,port))
{
QMessageBox::critical(this,"error","启动失败");
return ;
}
//启动成功
QMessageBox::information(this,"success","启动成功");
//设置编辑器不可用
ui->lineEdit->setEnabled(false);
//按钮文本设置为关闭
ui->pushButton->setText("关闭");
//此时如果客户端发来请求,服务器自动发送newConnection信号
//连接
connect(server,&QTcpServer::newConnection, this,&Widget::newConnection_slot);
}else
{
//关闭服务器
server->close();
//移除链表
for(int i=0;i<socketList.size();i++)
{
socketList.removeAt(i);
}
//设置编辑器可用
ui->lineEdit->setEnabled(true);
//按钮文本设置为关闭
ui->pushButton->setText("启动");
}
}
//处理newConnection槽函数
void Widget::newConnection_slot()
{
qDebug()<<"有客户端发来连接";
//获取客户端套接字地址
QTcpSocket * s = server->nextPendingConnection();
//放入客户端链表
socketList.push_back(s);
//此时若有客户端发来数据,则客户端套接字发送readyRead信号
//连接
connect(s,&QTcpSocket::readyRead, this,&Widget::readyRead_slot);
}
//处理readyRead槽函数
void Widget::readyRead_slot()
{
//1、遍历链表的所有客户端,把未连接客户端移除链表
for(int i=0;i<socketList.size();i++)
{
//判断是否失效
if(socketList[i]->state()==0)
{
//移除链表
socketList.removeAt(i);
}
}
//2、遍历客户端,判断可读数据
for(int i=0;i<socketList.count();i++)
{
if(socketList[i]->bytesAvailable()!=0)
{
//读取
QByteArray msg = socketList[i]->readAll();
//展示
ui->listWidget->addItem(QString::fromLocal8Bit(msg));
//发给其他客户端
for(int j=0;j<socketList.length();j++)
{
if(i!=j)
{
socketList[j]->write(msg);
}
}
}
}
}
客户端
头文件:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket> //TCP客户端
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_connectBtn_clicked();
void connected_slot();
void readyRead_slot();
void on_sendBtn_clicked();
void on_cancelBtn_clicked();
void disconnected_slot();
private:
Ui::Widget *ui;
QTcpSocket *client;
QString userName;
};
#endif // WIDGET_H
源文件:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//实例化客户端
client = new QTcpSocket(this);
//readyRead
connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
//若成功连接,客户端会自动发送connected信号
//连接
connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
//断开后发disconnected信号
//连接
connect(client,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);
}
Widget::~Widget()
{
delete ui;
}
//连接服务器槽函数
void Widget::on_connectBtn_clicked()
{
//获取UI界面数据
QString ip = ui->ipEdit->text();
quint16 port = ui->portEdit->text().toUInt();
userName = ui->nameEdit->text();
//连接服务器
client->connectToHost(ip,port);
}
void Widget::connected_slot()
{
QMessageBox::information(this,"成功","连接成功");
//禁用
ui->ipEdit->setEnabled(false);
ui->nameEdit->setEnabled(false);
ui->portEdit->setEnabled(false);
ui->connectBtn->setEnabled(false);
//向服务器发送一条消息
QString msg = userName + ":进入聊天室";
client->write(msg.toLocal8Bit());
}
void Widget::readyRead_slot()
{
//读取数据
QByteArray msg = client->readAll();
//展示
ui->msgListWidget->addItem(QString::fromLocal8Bit(msg));
}
//发消息槽函数
void Widget::on_sendBtn_clicked()
{
//组织要发的消息
QString msg = userName + ": " + ui->msgEdit->text();
//发消息
client->write(msg.toLocal8Bit());
//展示
QListWidgetItem *item = new QListWidgetItem(msg);
item->setTextAlignment(Qt::AlignRight);
ui->msgListWidget->addItem(item);
// ui->msgListWidget->addItem(msg);
//清空消息
ui->msgEdit->clear();
}
//取消槽函数
void Widget::on_cancelBtn_clicked()
{
//准备发消息给服务器
QString msg = userName + ": 离开聊天室";
client->write(msg.toLocal8Bit());
//断开连接
client->disconnectFromHost();
}
void Widget::disconnected_slot()
{
QMessageBox::information(this,"提示","取消连接成功");
//启用
ui->ipEdit->setEnabled(true);
ui->nameEdit->setEnabled(true);
ui->portEdit->setEnabled(true);
ui->connectBtn->setEnabled(true);
}
运行结果:
3.思维导图