QT C++之保存界面设置为配置文件

案例描述:UDP网口通信IP端口配置。建立NetSet类。

功能概述:在Qt应用程序中实现界面配置的持久化存储,允许用户保存和加载网络连接参数(本地IP、本地端口、目标IP、目标端口),使配置在程序重启后仍然有效。

界面:

头文件netset.h:

cpp 复制代码
#ifndef NETSET_H
#define NETSET_H

#include <QDialog>

namespace Ui {
class NetSet;
}

class NetSet : public QDialog
{
    Q_OBJECT

public:
    explicit NetSet(QWidget *parent = nullptr);
    ~NetSet();

    QString g_locip = "";
    int g_locport = 0;
    QString g_dstip = "";
    int g_dstport = 0;

private:
    void loadConfig();  // 从配置文件读取配置
    void saveConfig();     // 保存配置到文件

private slots:
    void on_pushButton_connect_clicked(); // 连接按钮
    void on_pushButton_disconnect_clicked(); // 断开连接按钮

signals:
    void configChanged();  // 配置改变信号
    void disConnect();     // 断开连接信号

private:
    Ui::NetSet *ui;
    QString configFilePath;  // 配置文件路径

};

#endif // NETSET_H

源文件netset.cpp:

cpp 复制代码
#include "netset.h"
#include "ui_netset.h"
#include "netConnect.h"
#include <QHostAddress>
#include <QNetworkInterface>
#include <QFileInfo>
#include <QSettings>  // 配置文件的头

NetSet::NetSet(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::NetSet)
{
    ui->setupUi(this);
    setWindowTitle("配置窗口");

    // 设置配置文件路径(与可执行文件同目录)
    configFilePath = QCoreApplication::applicationDirPath() + "/config.ini";
    //    qDebug() << "配置文件路径:" << configFilePath;

    // 从配置文件加载设置
    loadConfig();

    // 填充IP地址列表
    //通过QNetworkInterface类来获取本机的IP地址和网络接口信息
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list)
    {
        if (address.protocol() == QAbstractSocket::IPv4Protocol)
        {
            qDebug() << "My localhost IPv4 address: " << address.toString();

            ui->comboBox_localip->addItem(address.toString());
        }
    }

    // 设置当前值
    int index = ui->comboBox_localip->findText(g_locip);
    if (index >= 0) {
        ui->comboBox_localip->setCurrentIndex(index);
    } else if (!g_locip.isEmpty()) {
        ui->comboBox_localip->addItem(g_locip);
        ui->comboBox_localip->setCurrentText(g_locip);
    }

    //    ui->comboBox_localip->setItemText(0, g_locip);
    ui->lineEdit_localport->setText(QString::number(g_locport));
    ui->lineEdit_destip->setText(g_dstip);
    ui->lineEdit_destport->setText(QString::number(g_dstport));
}

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

// 从配置文件加载设置
void NetSet::loadConfig()
{
    // 检查配置文件是否存在
    QFileInfo configFile(configFilePath);
    if (!configFile.exists()) {
        //qDebug() << "配置文件不存在,使用默认值"; // 中文报错
        //qDebug() << "NO";
        g_locip = "192.168.2.166";
        g_locport = 8899;
        g_dstip = "192.168.2.3";
        g_dstport = 8899;
        return;
    }

    // 打开配置文件
    QSettings settings(configFilePath, QSettings::IniFormat);

    // 读取服务器配置,如果读取失败则使用默认值
    QString ip = settings.value("Local/ip", "192.168.2.166").toString();
    quint16 port = settings.value("Local/port", 8899).toUInt();
    QString destip = settings.value("Dest/ip", "192.168.2.3").toString();
    quint16 destport = settings.value("Dest/port", 8899).toUInt();

    // 验证端口号是否有效
    if (port < 1 || port > 65535) {
        qDebug() << "端口号无效,使用默认值8899";
        port = 8899;
    }
    if (auvport < 1 || auvport > 65535) {
        qDebug() << "端口号无效,使用默认值8899";
        destport = 8899;
    }

    // 更新成员变量
    g_locip  = ip;
    g_locport  = port;
    g_dstip  = destip;
    g_dstport  = destport;

    qDebug() << "从配置文件加载配置:" << ip << ":" << port << destip << ":" << destport;
}

// 保存配置到文件
void NetSet::saveConfig()
{
    QSettings settings(configFilePath, QSettings::IniFormat);

    // 保存服务器配置
    settings.setValue("Local/ip", g_locip);
    settings.setValue("Local/port", g_locport);
    settings.setValue("Dest/ip", g_dstip);
    settings.setValue("Dest/port", g_dstport);

    // 立即写入文件
    settings.sync();

    qDebug() << "配置已保存: Local" << g_locip << ":" << g_locport
                 << "Dest" << g_dstip << ":" << g_dstport;
}

// 连接按钮
void NetSet::on_pushButton_connect_clicked()
{
    // 获取界面输入的值
    g_locip = ui->comboBox_localip->currentText();
    g_locport = ui->lineEdit_localport->text().toInt();
    g_dstip = ui->lineEdit_destip->text();
    g_dstport = ui->lineEdit_destport->text().toInt();

    saveConfig(); // 保存配置到文件

    // 方式1: 通过信号通知
    emit configChanged();

    // 方式2: 直接操作NetConnect对象(需要在NetSet中持有NetConnect指针)
    // if (netConnect) {
    //     netConnect->reloadConfig();
    //     netConnect->Connect();
    // }

    this->hide();
}

// 断开连接按钮
void NetSet::on_pushButton_disconnect_clicked()
{
    emit disConnect();
//    if (netConnect->isConnected()) {
//        netConnect->disconnectFromServer(); // 断开连接
//    }
}

配置文件保存功能实现笔记

一、功能概述

在Qt应用程序中实现界面配置的持久化存储,允许用户保存和加载网络连接参数(本地IP、本地端口、目标IP、目标端口),使配置在程序重启后仍然有效。

二、技术选型

使用QSettings类

QSettings是Qt提供的配置文件读写类,支持多种格式:

  • IniFormat:标准的.ini格式文件,人类可读

  • NativeFormat:Windows注册表或macOS的plist

  • XmlFormat:XML格式

本项目采用QSettings::IniFormat,便于调试和手动修改。

三、核心实现步骤

1. 定义配置文件路径

cpp 复制代码
// 构造函数中设置路径,与可执行文件同目录
configFilePath = QCoreApplication::applicationDirPath() + "/config.ini";

2. 成员变量设计

cpp 复制代码
// 存储配置数据的成员变量
QString g_locip = "";   // 本地IP
int g_locport = 0;      // 本地端口
QString g_dstip = "";   // 目标IP
int g_dstport = 0;      // 目标端口

3. 加载配置(loadConfig)

实现流程:

步骤 操作 说明
1 检查文件是否存在 使用QFileInfo::exists()
2 不存在则使用默认值 防止程序崩溃
3 创建QSettings对象 指定路径和格式
4 读取配置值 提供默认值作为后备
5 验证数据有效性 如端口号范围检查
6 更新成员变量 供界面显示使用

关键代码:

cpp 复制代码
QSettings settings(configFilePath, QSettings::IniFormat);
QString ip = settings.value("Local/ip", "192.168.2.166").toString();
quint16 port = settings.value("Local/port", 8899).toUInt();

4. 保存配置(saveConfig)

实现流程:

步骤 操作 说明
1 创建QSettings对象 指定路径和格式
2 写入配置值 使用分组/键结构
3 调用sync() 立即写入磁盘
4 输出调试信息 便于排查问题

关键代码:

cpp 复制代码
settings.setValue("Local/ip", g_locip);
settings.setValue("Local/port", g_locport);
settings.sync();  // 确保立即写入文件

5. 配置文件的组织结构

复制代码
[Local] 
ip=192.168.2.166 
port=8899 
[Dest] 
ip=192.168.2.3 
port=8899

四、界面与配置的交互流程

初始化流程

复制代码
构造函数启动
    ↓
设置配置文件路径
    ↓
loadConfig() → 读取文件/默认值 → 更新成员变量
    ↓
填充IP下拉列表
    ↓
将成员变量值显示到界面控件

保存流程(点击连接按钮)

复制代码
用户点击"连接"按钮
    ↓
从界面控件获取用户输入
    ↓
更新成员变量(g_locip/g_locport等)
    ↓
saveConfig() → 写入配置文件
    ↓
emit configChanged() → 通知其他模块
    ↓
隐藏配置窗口
相关推荐
谭欣辰2 小时前
C++ 堆 的基础与 二叉堆详解
开发语言·c++
Ulyanov2 小时前
《PySide6 GUI开发指南:QML核心与实践》 第十篇:综合实战——构建完整的跨平台个人管理应用
开发语言·python·qt·ui·交互·qml·雷达电子战系统仿真
ian4u2 小时前
车载 Android C++ 完整技能路线:从基础到进阶
android·开发语言·c++
郝学胜-神的一滴2 小时前
[力扣 227] 双栈妙解表达式计算:从思维逻辑到C++实战,吃透反向波兰式底层原理
java·前端·数据结构·c++·算法
-凌凌漆-2 小时前
【QML】QQmlEngine::setObjectOwnership()的作用
qt
Yuk丶3 小时前
Procedural Dialogue Engine - UE4程序化对话系统的技术实现
c++·游戏引擎·ue4·游戏程序·虚幻
自信150413057593 小时前
重生之从0开始学习c++之string(上)
开发语言·c++·学习
BestOrNothing_20153 小时前
C++零基础到工程实战(4.3.8):基于 vector 实现一个简易缓存数据库
c++·vector·string·缓存数据库·stringstream·键值存储·getline
苏宸啊3 小时前
C++异常
c++