qt定时器,绘制,简单网络通讯 2024.10.10

发布于:2024-10-11 ⋅ 阅读:(12) ⋅ 点赞:(0)

1.绘制时钟并且转动:
整体逻辑就是使用计时器QTimer定时修改坐标系。
绘制部分:使用QPainter创建画板,中心位于窗口中心,设置画板大小,在根据中心绘制边缘和针,然后使用rolate进行旋转

1.MainWindow.cpp
#include "mainwindow.h"
#include <QPainter>
#include <QTimer>
#include <QTime>

//整体逻辑就是使用计时器QTimer定时修改坐标系。
//绘制部分:使用QPainter创建画板,中心位于窗口中心,设置画板大小,在根据中心绘制边缘和针,然后使用rolate进行旋转
MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
    // 创建定时器
    QTimer *timer = new QTimer(this);
    //参数设定发送信号者为定时器,发送信号为timeout,接受者为本类实例,接受函数为本类的update
    // QOverload<>::of(&MainWindow::update)进一步解释 QOverload<>注释为指向无参函数,of指向函数指针
    //update虽然没有在MainWindow显式声明,但是继承的QWidget有。这个函数会触发paintEvent(),重新绘制坐标系
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&MainWindow::update));
    timer->start(1000);  // 每秒刷新一次
}

void MainWindow::paintEvent(QPaintEvent *) {
    QTime time = QTime::currentTime();  // 获取当前时间
    int hour = time.hour();
    int minute = time.minute();
    int second = time.second();

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 开启抗锯齿
    //Qmin为获取较小的那个
    int side = qMin(width(), height());
    painter.setViewport((width() - side) / 2, (height() - side) / 2, side, side);
    //设置painter的中心点为这个window的中心
    painter.setWindow(-50, -50, 100, 100);  // 设置画盘的大小

    // 绘制时钟表盘
    drawClockFace(&painter);

    // 计算指针的角度
    //关于这边save()和restore(),对于多次的重复绘制,需要使用restore恢复到save之前状态避免影响后续的绘制
    painter.save();
    //时针逻辑:360/12=30,30*(当前小时+分针换算的小时)
    //分针逻辑:360/60=6.6*(当前分钟数+秒换算成分钟)
    //秒针逻辑:360/60=6,6*秒数
    painter.rotate(30.0 * ((hour + minute / 60.0)));
    drawHand(&painter, 6, Qt::black);
    painter.restore();

    painter.save();
    painter.rotate(6.0 * (minute + second / 60.0));  // 分针每分钟转动6度
    drawHand(&painter, 4, Qt::blue);
    painter.restore();

    painter.save();
    painter.rotate(6.0 * second);  // 秒针每秒转动6度
    drawHand(&painter, 2, Qt::red);
    painter.restore();
}

void MainWindow::drawClockFace(QPainter *painter) {
    painter->setPen(Qt::black);
    for (int i = 0; i < 12; ++i) {
        painter->drawLine(40, 0, 50, 0);  // 绘制刻度线
        painter->rotate(30.0);  // 每次旋转30度,绘制下一个刻度
    }
}

void MainWindow::drawHand(QPainter *painter, int width, const QColor &color) {
    static const QPoint points[3] = {QPoint(0, 5), QPoint(0, -30), QPoint(5, 0)};
    painter->setBrush(color);
    painter->drawPolygon(points, 3);  // 画一个三角形指针
}

2.MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QWidget>

class QPainter;

class MainWindow : public QWidget {
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);  // 构造函数

protected:
    // 处理绘制事件
    void paintEvent(QPaintEvent *event) override;

private:
    // 绘制时钟表盘
    void drawClockFace(QPainter *painter);

    // 绘制指针(时针、分针、秒针)
    void drawHand(QPainter *painter, int width, const QColor &color);
};

#endif // MAINWINDOW_H

3.main.cpp

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MainWindow window;
    window.resize(200, 200);
    window.show();

    return app.exec();
}

2.简单的服务器和客户端通信:主要要在.pro文件添加network

QT       += core gui network

服务器cpp

#include "myserver.h"

MyServer::MyServer(QWidget *parent) : QWidget(parent)
{
    server = new QTcpServer(this);
    connect(server, &QTcpServer::newConnection, this, &MyServer::handleNewConnection);

    QVBoxLayout *layout = new QVBoxLayout(this);
    logTextEdit = new QTextEdit(this);
    logTextEdit->setReadOnly(true);
    layout->addWidget(logTextEdit);
    startButton = new QPushButton("服务器启动", this);
    layout->addWidget(startButton);

    connect(startButton, &QPushButton::clicked, this, &MyServer::startServer);
}

MyServer::~MyServer() {
    delete server;
}

void MyServer::startServer() {
    if (server->listen(QHostAddress::Any, 1234)) {
        logTextEdit->append("服务器启动");
    } else {
        logTextEdit->append("服务器启动失败");
    }
}

void MyServer::handleNewConnection() {
    QTcpSocket *clientSocket = server->nextPendingConnection();
    connect(clientSocket, &QTcpSocket::readyRead, [this, clientSocket]() {
        QByteArray data = clientSocket->readAll();
        logTextEdit->append("收到的消息: " + data);
        clientSocket->write("消息收到了");
    });
}

.h

#ifndef MYSERVER_H
#define MYSERVER_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>

class MyServer : public QWidget
{
    Q_OBJECT

public:
    MyServer(QWidget *parent = nullptr);
    ~MyServer();

private slots:
    void startServer();
    void handleNewConnection();

private:
    QTcpServer *server;
    QTextEdit *logTextEdit;
    QPushButton *startButton;
};

#endif // MYSERVER_H

main

#include <QApplication>
#include "myserver.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyServer server;
    server.resize(400, 300);
    server.show();



    return app.exec();
}

客户端cpp

#include "myclient.h"

MyClient::MyClient(QWidget *parent)
    : QWidget(parent)
{
    socket = new QTcpSocket(this);

    QVBoxLayout *layout = new QVBoxLayout(this);
    messageInput = new QLineEdit(this);
    sendButton = new QPushButton("发送", this);
    responseTextEdit = new QTextEdit(this);
    responseTextEdit->setReadOnly(true);

    layout->addWidget(messageInput);
    layout->addWidget(sendButton);
    layout->addWidget(responseTextEdit);

    connect(sendButton, &QPushButton::clicked, this, &MyClient::sendMessage);
    connect(socket, &QTcpSocket::readyRead, this, &MyClient::readData);
}

MyClient::~MyClient() {
    socket->close();  // 关闭socket连接
}

void MyClient::connectToServer(const QString &host, quint16 port) {
    socket->connectToHost(host, port);
}

void MyClient::sendMessage() {
    QString message = messageInput->text();
    socket->write(message.toUtf8());
}

void MyClient::readData() {
    QByteArray data = socket->readAll();
    responseTextEdit->append("服务器: " + data);
}

.h

#ifndef MYCLIENT_H
#define MYCLIENT_H

#include <QWidget>
#include <QTcpSocket>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>

class MyClient : public QWidget
{
    Q_OBJECT

public:
    MyClient(QWidget *parent = nullptr);
    ~MyClient();

    void connectToServer(const QString &host, quint16 port);  // 连接服务器函数

private slots:
    void sendMessage();  // 发送消息槽
    void readData();     // 读取数据槽

private:
    QTcpSocket *socket;        // QTcpSocket 实例
    QLineEdit *messageInput;   // 输入框
    QPushButton *sendButton;   // 发送按钮
    QTextEdit *responseTextEdit; // 显示响应消息的文本框
};

#endif // MYCLIENT_H

main

#include <QApplication>

#include "myclient.h"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);


    MyClient client;
    client.connectToServer("127.0.0.1", 1234);  // 假设服务器在本地
    client.resize(400, 300);
    client.show();

    return app.exec();
}