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();
}