Qt_笔记

1.事件 


  举例:按键事件使用:包含QKeyEvent头文件。h文件里声明,cpp重写虚函数:

void keyPressEvent(QKeyEvent *k)
即可。事件的名称和获取事件的函数等细节可以在帮助里查找。

2.TCP网络:

  需要在pro文件里第一行添加一个库名network。

  要包含头文件QTcpSocket 和QHostAddress(需要把IP地址转换为该类型),如果是服务器还要额外包含一个库QTcpServer。

  客户端:

  使用QTcpSocket 创建一个socket对象,函数connectToHost连接。连接成功/连接断开会发出信号,connect到一个槽函数或lambda。

  当 QTcpSocket 对象成功连接到服务器后,只要有数据到达并可读,就会触发 QTcpSocket::readyRead 信号,connect到读的槽函数即可。

  服务端:

  创建一个QTcpServer对象,调用listen函数进行监听。客户端发起连接时会发出信号QTcpServer::newConnection,然后在槽里使用QTcpServer::nextPendingConnection()会返回一个QTcpSocket对象,该QTcpSocket对象已经进行了连接。

  使用QTcpSocket::write函数来写。QTcpSocket::readAll来读。读写的格式是QByteArray(普通c++是char *格式)。

  普通c++的一个socket可以连接多个socket,但是qt的每个QTcpSocket对象只能连接一个QTcpSocket对象。

  槽函数中可以使用sender()函数,返回信号的发生者的指针(要接收的话需要强转)。

3.ui文件外控制该ui:

  使用signal: 关键字自定义信号,然后使用connect绑定信号与ui内部的槽函数,可以使用参数传递信息。自定义信号不需要函数的实现,发出时使用emit +函数即可。

  

4.qt嵌入式qml的方法

// 在 QQuickView 或 QQmlApplicationEngine 中加载 QML 文件
QQuickView *view = new QQuickView;
view->setSource(QUrl("./qrc/battery.qml"));

  

5. qt设置控件的背景图片的两种常用方法

 (1)样式表qss设置border-image

  可以代码中用 "控件->setStyleSheet()" 集成,也可以写在qss文件中,然后代码中用set加载qss文件。

//感觉border-image比background-image好用,background-image有时候设置之后无效
ui->KongJianName->setStyleSheet("border-image=url(":/..."); padding:0px 0px;");  //要设置padding,不然有时候无法正常显示

  如果将qss写到单独的qss文件中,可以用过以下方式读取qss然后进行设置:

    QFile style("/usr/test/milliin/qss/QTabWidget.qss");
    if(style.open(QFile::ReadOnly))
    {
        QString styleString = QString::fromUtf8(style.readAll());
        ui->KongJianName->setStyleSheet(styleString);
        style.close();
    }

(2)设置Pixmap

ui->KongJianName->setPixmap(QPixmap(".../path").scaled(ui->KongJianName->size(), Qt::IgnoreAspectRadio, Qt::SmoothTransformation));

6.QState状态机

代码示例:

h:

#ifndef STATEDEMO_H
#define STATEDEMO_H

#include <QWidget>
#include <QState>
#include <QStateMachine>
#include <QHistoryState>
#include <QFinalState>
#include <QTimer>

QT_BEGIN_NAMESPACE
namespace Ui { class StateDemo; }
QT_END_NAMESPACE

class StateDemo : public QWidget
{
    Q_OBJECT

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

private:
    Ui::StateDemo *ui;
};
#endif // STATEDEMO_H

cpp:

#include "StateDemo.h"
#include "ui_StateDemo.h"

StateDemo::StateDemo(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::StateDemo)
{
    ui->setupUi(this);

    //创建状态机
    QStateMachine *machine = new QStateMachine(this);

    //创建状态
    QState *idleState= new QState(machine);
    QState *workState= new QState(machine);
    QState *pauseState= new QState(machine);
    //创建结束状态
    QFinalState *finalState= new QFinalState(machine);

    //创建workState的子状态
    QState *step1 = new QState(workState);
    QState *step2 = new QState(workState);
    //设置子状态初始状态
    workState->setInitialState(step1);

    //创建历史状态 记住工作状态最后一个子状态
    QHistoryState *historyState= new QHistoryState(workState);

    //设置状态转换
    idleState->addTransition(ui->workBtn, &QPushButton::clicked, workState);  //语法有点像connect
    workState->addTransition(ui->pauseBtn, &QPushButton::clicked, pauseState);
    pauseState->addTransition(ui->workBtn, &QPushButton::clicked, historyState);

    QTimer* timer1= new QTimer(step1);
    timer1->setInterval(1000);
    timer1->setSingleShot(true);
    connect(step1, &QState::entered, timer1, QOverload<>::of(&QTimer::start));   //由于start有多个重载函数,所以这里要用 QOverload<参数>::of() 来指定
    step1->addTransition(timer1, &QTimer::timeout, step2);

    QTimer* timer2= new QTimer(step2);
    timer2->setInterval(1000);
    timer2->setSingleShot(true);
    connect(step2, &QState::entered, timer2, QOverload<>::of(&QTimer::start));   //由于start有多个重载函数,所以这里要用 QOverload<参数>::of() 来指定
    step2->addTransition(timer2, &QTimer::timeout, step1);

    //设置状态机初始状态
    machine->setInitialState(idleState);
    machine->start();

    //连接状态进入信号来更新界面
    connect(idleState, &QState::entered, [this]{
        ui->label_state->setText("状态:空闲");
    });

    connect(workState, &QState::entered, [this] {
        ui->label_state->setText("状态: 工作中");
    });

    connect(pauseState, &QState::entered, [this] {
        ui->label_state->setText("状态: 已暂停");
    });

    connect(step1, &QState::entered, [this] {
        ui->label_state->setText("状态: 工作中 - 步骤1");
    });

    connect(step2, &QState::entered, [this] {
        ui->label_state->setText("状态: 工作中 - 步骤2");
    });

    connect(finalState, &QState::entered, [this] {
        ui->label_state->setText("状态: 完成");
    });

    connect(machine, &QStateMachine::finished, [this]{
        ui->label_state->setText("状态: 状态机结束");
    });




}

StateDemo::~StateDemo()
{
    delete ui;
}

7.添加新的Widget类

Qt设计师界面类 添加一个Widget类即可

8.字符串数据解析(QString和QTextStream)

(1)QString::split
  用于将包含分隔符(如逗号、空格、制表符)的字符串分割成多个部分。

QString data = "Apple,Banana,Cherry,Date";
QStringList fruits = data.split(",");
// fruits: ["Apple", "Banana", "Cherry", "Date"]

// 处理更复杂的分隔符,可以使用正则表达式
QString complexData = "One|Two;Three Four";
QStringList parts = complexData.split(QRegExp("[|; ]")); // 使用 | ; 或空格 分割
// parts: ["One", "Two", "Three", "Four"]

(2)截取部分字符串  QString::mid, QString::left, QString::right, QString::section

QString fixedFormat = "NAME:John Doe AGE:30";
QString name = fixedFormat.mid(5, 8); // 从位置5开始,取8个字符 -> "John Doe"
QString ageStr = fixedFormat.mid(15); // 从位置15开始到末尾 -> "30"

// `section` 更强大,按分隔符截取“段”
QString path = "/usr/local/bin/app";
QString secondDir = path.section('/', 2, 2); // 从0开始计数,第2段 -> "local"

left和right可以输出从字符串的左侧和右侧截取指定长度的字符
QString str = "Hello, World!";
qDebug() << str.left(5);    // 输出: "Hello"
qDebug() << str.right(6);   // 输出: "World!"

(3)去除空白字符  QString::trimmed,  QString::simplified

QString dirtyString = "   Hello, World!   \n";
QString cleanString = dirtyString.trimmed(); // "Hello, World!"
QString superClean = dirtyString.simplified(); // "Hello, World!" (同时将内部连续空格变为一个空格)

(4)数字与字符串转换  QString::toInt, QString::toDouble, QString::toFloat 等
  将字符串表示的数值转换回基本数据类型。

(5)QTextStream 构建流对象
可以从 QFile, QString(!), QByteArray 等构建。

// 从文件构建
QFile file("data.txt");
if (file.open(QIODevice::ReadOnly)) {
    QTextStream in(&file);
    // ... 使用 in 读取
}

// **从 QString 构建 (非常关键!)**
QString dataString = "123 3.14 Hello";
QTextStream stream(&dataString, QIODevice::ReadOnly); // 将字符串本身作为数据源

(6) 处理行 QTextStream::readLine
通常用于逐行读取文件,然后对每一行再进行解析。

QFile file("data.csv");
if (file.open(QIODevice::ReadOnly)) {
    QTextStream in(&file);
    while (!in.atEnd()) {
        QString line = in.readLine(); // 读取一行
        QStringList fields = line.split(",");
        // 处理 fields...
    }
}

(7)QTextStream  operator>>
  流操作符 >> 会跳过空白字符(空格、换行、制表符),直到找到非空白数据,然后尝试将其转换为目标类型。

QString line = "100 3.1415926 true";
QTextStream in(&line);

int id;
double pi;
bool status;

in >> id >> pi >> status; // 自动进行字符串到类型的转换

qDebug() << id;    // 输出: 100
qDebug() << pi;     // 输出: 3.14159
qDebug() << status; // 输出: true

在读取后,可以检查流的状态:

QTextStream in(someString);
int a, b;
in >> a >> b;

if (in.status() != QTextStream::Ok) {
    // 处理读取错误
}
in.resetStatus(); // 重置错误状态,以便后续读取

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值