QT截图系列1-配置文件改变区域主题

效果

设置页面控制截图区域的主题,如图所示,通过Tab页的设置可以改变截图区域边界的颜色,宽度和线条样式

20220723-001611

原理

页面修改相关参数,比如宽度或者颜色,本质是利用QJson往json文件里写,在绘制截图区域时,又可以从json文件中读,这就是实现设置页面控制截图区域的原理。

在这里插入图片描述

相关实现

原理实现

先说明QJson和Json的不同,QJson属于QT自带的一个模块,Json属于开源库;QJson相比于Json,Json很多方法都已经写好了,最重要的一个方法就是

auto root = json::parse("{}");

通过它可以解析json文件,并实现set和get(通过[][][]级联的方式实现对子节点的读写,无论其有多深),例如

Json::Reader reader;
Json::Value root;
ifstream file("demo.json", ios::binary);
reader.parse(file, root);
// 读取
string friend_name = root["friends"]["friend_name"].asString();
// 写入
root["friends"]["friend_name"] = Json::Value("man");

但是QJson并没有类似于parse的方法,这个是最核心的,因此单纯使用QJson自带的的函数,是无法做到读写深层次的子节点数据。
这是我本地环境的json文件

{
    "signalflag": {
        "ar": {
            "anchor": {
                "color": "#ff55ff7f"
            },
            "border": {
                "color": "#ffaa0000",
                "linetype": "4",
                "width": "3"
            }
        },
        "clipboard": "F2",
        "screenshot": "F1",
        "trayiconcolor": "2"
    }
}

可见,如果想要读写border节点下的相关数据,就必须实现类似于Json下parse的功能。
方法:递归

// 写 使用递归获取sPath对应的节点信息
void JsonPrivate::SetValue(QJsonObject& parent, const QString& sPath, const QJsonValue& newValue) 
{
    const int indexOfDot = sPath.indexOf('.');         // 解析“.”
    const QString sProperty = sPath.left(indexOfDot);  // 获取节点对应的属性
    const QString sRestPath = (indexOfDot > 0) ? path.mid(indexOfDot + 1) : QString(); 
    QJsonValue fieldValue = parent[sProperty];

    if (sRestPath.isEmpty()) 
    {
        return;          // 不存在直接返回
    }
    else 
    {
        // 路径中间的属性,递归访问它的子属性
        QJsonObject child = parent[sProperty].toObject();
        setValue(child, sRestPath , newValue);
        parent[sProperty] = child; 
    }
}

// 读 不用使用递归 常规方法即可
QJsonValue JsonPrivate::GetValue(const QString& sPath, const QJsonObject& fromNode) const
{
    QJsonObject parent = fromNode.isEmpty() ? root : fromNode;
    QStringList names = sPath.split(QRegularExpression("\\."));     // 正则表达式解析
    
    int iSize = names.size();
    for (int i = 0; i < iSize  - 1; ++i) 
    {
        if (parent.isEmpty()) 
        {
            return QJsonValue();
        }
        parent = parent.value(names.at(i)).toObject();    // 重点 QJsonObject可以直接赋值
    }

    // [4] 返回 parent 中属性名为倒数第一个属性名字对应的属性值
    return parent.value(names.last());
}

通过以上方法可以实现在QJson中对任意深度节点的json文件实现读写

界面实现

主要利用模块QTabWidget实现Tab页的切换,目前有四个Tab页
在这里插入图片描述
以第一个页面为例,代码简述,其余均类似

void Settings::SetupGeneralDisplay()
{
    auto index = m_Tabwidget->addTab(new QWidget(), tr("General"));
    auto layout = new QVBoxLayout();
    layout->setSpacing(15);

    // 语言
    auto tempLanguageLy = new QHBoxLayout();
    auto tempLanguage = new QLabel(tr("Language: "));

    auto ctrlLanguage = new QComboBox();
    ctrlLanguage->setView(new QListView());
    ctrlLanguage->view()->window()->setWindowFlag(Qt::NoDropShadowWindowHint);
    ctrlLanguage->addItem("English");
    QString sTemp = "Chinese";
    ctrlLanguage->addItem(sTemp);

    tempLanguageLy->addWidget(tempLanguage);
    tempLanguageLy->addWidget(ctrlLanguage);
    tempLanguageLy->addStretch();
    
    // 锚点颜色
    auto ctrlAnchorColorLy = new QHBoxLayout();
    auto tempAnchorColor = new QLabel(tr("AnchorColor: "));

    auto ctrlAnchorColor = new ColorDialogButton(config.GetJsonValue("signalflag.ar.anchor.color"));
    connect(ctrlAnchorColor, &ColorDialogButton::eChange, [this](auto&& color)
    {
        QString temp = ConvertColor2Str(color);
        config.SetJsonValue("signalflag.ar.anchor.color", temp);
    });
    ctrlAnchorColor->setFixedSize(23, 23);

    ctrlAnchorColorLy->addWidget(tempAnchorColor);
    ctrlAnchorColorLy->addWidget(ctrlAnchorColor);
    ctrlAnchorColorLy->addStretch();

    // 托盘图标颜色
    auto trayIconColorLy = new QHBoxLayout();
    auto tempTrayIconColor = new QLabel(tr("TrayIconColor: "));

    auto chooseTrayIconColorBlock = new QButtonGroup();
    chooseTrayIconColorBlock->setExclusive(true);
    auto TrayIconColorAuto = new QRadioButton();
    TrayIconColorAuto->setText("Auto");
    TrayIconColorAuto->setChecked(1);            // 默认选中薯条
    auto TrayIconColorRGB = new QRadioButton();
    TrayIconColorRGB->setText("RGB");
    //TrayIconColorRGB->setIcon();
    //TrayIconColorRGB->setIconSize();

    chooseTrayIconColorBlock->addButton(TrayIconColorAuto, 1);
    chooseTrayIconColorBlock->addButton(TrayIconColorRGB, 2);

    trayIconColorLy->addWidget(tempTrayIconColor);
    trayIconColorLy->addWidget(TrayIconColorAuto);
    trayIconColorLy->addWidget(TrayIconColorRGB);
    trayIconColorLy->addStretch();

    connect(chooseTrayIconColorBlock, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, [this](int id)
    {
        config.SetJsonValue("signalflag.trayiconcolor", QString::number(id));
    });

    // 子Layout添加到总Layout
    layout->addLayout(tempLanguageLy);
    layout->addLayout(ctrlAnchorColorLy);
    layout->addLayout(trayIconColorLy);
    layout->addStretch();

    m_Tabwidget->widget(index)->setLayout(layout);
}

功能实现

原理肯定是QT的信号槽,信号槽如何使用请自行百度,这里不做讲解。
功能实现以截图区域的边界颜色为例

	// 写入
    auto ctrlARBorderColorLy = new QHBoxLayout();
    auto tempARBorderColor = new QLabel(tr("ARBorderColor: "));

	// 获取颜色
    auto ctrlARBorderColor = new ColorDialogButton(config.GetJsonValue("signalflag.ar.border.color"));
    // 颜色改变时触发
    connect(ctrlARBorderColor, &ColorDialogButton::eChange, [this](auto&& color)
    {
        QString temp = ConvertColor2Str(color);                  // RGBA转换为16进制 便于json中存储
        config.SetJsonValue("signalflag.ar.border.color", temp); // 写入json文件中
    });

// 读取
// 边界颜色 线宽 线条 
// 锚点大小和颜色
void ActiveRegion::rUpdateTheme()
{
	auto& config = Config::instance(GetJsonPath(eJsonPath::ChangedPath));  // 单例模式

	auto sSelectorBorderColor = config.GetJsonValue("signalflag.ar.border.color"); // 从json文件中获取对应的属性
	rSetBorderColor(ConvertStr2Color(sSelectorBorderColor));

	//auto iWidth = config.GetJsonValue("signalflag.ar.border.width").toInt();
	//rSetBorderWidth(iWidth);

	//auto iLineType = config.GetJsonValue("signalflag.ar.border.linetype").toInt();
	//rSetBorderStyle(Qt::PenStyle(iLineType));

	//auto sSelectorAnchorColor = config.GetJsonValue("signalflag.ar.anchor.color");
	//rSetAnchorBorderColor(ConvertStr2Color(sSelectorAnchorColor));

	//m_ActiveRegionBox.SetARAnchorWidth(iWidth);
}

总结

以上就是”QT截图系列1-配置文件改变区域主题“的核心内容,代码很多,不便展开。后续会陆续更新QT截图的博客,欢迎大家广泛提意见,我也可以做相关的修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值