QtC++中的代码优化——if嵌套篇

本文介绍了如何通过简化信号槽连接和使用映射关系来避免代码重复,解决if嵌套问题,提升Qt应用程序的代码优雅度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 一、简化重复结构的信号槽连接

1.先看代码

void TOVChanged();
void TOVDelayChanged();
void TOVRChanged();
void TOVRDelayChanged();
//类似的槽函数…………

void LiBatteryManagerSys::TOVChanged()
{
	float newData = ui->lineEdit_TOV->text().toFloat();
	int writeInt = newData * 10;
	m_communicator->writeTOV(writeInt);
}

void LiBatteryManagerSys::TOVDelayChanged()
{
	float newData = ui->lineEdit_TOVDelay->text().toFloat();
	int writeInt = newData * 10;
	m_communicator->writeTOVDelay(writeInt);
}

void LiBatteryManagerSys::TOVRChanged(){
//…………
}

void LiBatteryManagerSys::TOVRDelayChanged(){
//…………
}
//…………

connect(ui->lineEdit_TOV,&QLineEdit::editingfinished,this,&LiBatteryManagerSys::TOVChanged);
connect(ui->lineEdit_TOVDelay,&QLineEdit::editingfinished,this,&LiBatteryManagerSys::TOVDelayChanged);
//…………

 可以看到这段代码中的代码重复性很高,而且会需要连接多对信号槽。这样使得代码很不优雅。

2.解决方法

找到代码的共性:都是由QLineEdit类发出,由主窗口LiBatteryManagerSys类接收。因此可以修改为:

void LiBatteryManagerSys::valueChanged()
{
    QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender());
    if (!lineEdit)
        return;

    float newData = lineEdit->text().toFloat();
    int writeInt = newData * 10;

    if (lineEdit == ui->lineEdit_TOV) {
        m_communicator->writeTOV(writeInt);
    } else if (lineEdit == ui->lineEdit_TOVDelay) {
        m_communicator->writeTOVDelay(writeInt);
    } else if (lineEdit == ui->lineEdit_TOVR) {
        m_communicator->writeTOVR(writeInt);
    } else if (lineEdit == ui->lineEdit_TOVRDelay) {
        m_communicator->writeTOVRDelay(writeInt);
    }
}

connect(ui->lineEdit_TOV, &QLineEdit::textChanged, this, &LiBatteryManagerSys::valueChanged);
connect(ui->lineEdit_TOVDelay, &QLineEdit::textChanged, this, &LiBatteryManagerSys::valueChanged);
//…………

二、优化if嵌套结构 

当简化了重复的信号槽的问题时,又产生了新的问题——if嵌套语句。

if嵌套的结构写起来比较省事,但是看起来比较容易被鄙视,嵌套次数少还好 ,但是遇到像我这个项目,有几十上百个QLineEdit需要if来判断的时候,代码就显得非常的臃肿。

解决方法:建立映射关系

#include <QMap>

// 在类的声明中定义一个映射容器
QMap<QLineEdit*, std::function<void(int)>> lineEditActions;

// ...

void LiBatteryManagerSys::setupLineEditActions()
{
    lineEditActions[ui->lineEdit_TOV] = [this](int value) { m_communicator->writeTOV(value); };
    lineEditActions[ui->lineEdit_TOVDelay] = [this](int value) { m_communicator->writeTOVDelay(value); };
    lineEditActions[ui->lineEdit_TOVR] = [this](int value) { m_communicator->writeTOVR(value); };
    lineEditActions[ui->lineEdit_TOVRDelay] = [this](int value) { m_communicator->writeTOVRDelay(value); };
}

void LiBatteryManagerSys::valueChanged()
{
    QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender());
    if (!lineEdit)
        return;

    float newData = lineEdit->text().toFloat();
    int writeInt = newData * 10;

    auto actionIter = lineEditActions.find(lineEdit);
    if (actionIter != lineEditActions.end()) {
        actionIter.value()(writeInt);
    }
}

在类的构造函数中调用 setupLineEditActions() 来建立映射关系,然后在 valueChanged() 槽函数中使用这个映射来执行相应的操作。这种方法将逻辑与操作进行了分离,让代码看起来更加整洁和美观。

### Qt实现简易计算器的算法 要通过Qt框架实现一个简易计算器的功能,可以按照以下逻辑设计和实现其核心算法。以下是具体的设计思路和技术要点: #### 1. **界面布局** 利用Qt Designer工具创建图形化用户界面(GUI),通常会包含按钮(用于输入数字、运算符)、显示屏(显示当前输入的内容以及结果)。这些组件可以通过`QPushButton`和`QLabel`来完成。 对于简单的四则运算器来说,需要设置如下按键: - 数字键 (0~9) - 运算符 (+, -, *, /) - 功能键 (=, C 清屏) 这部分的具体实现可参考提供的链接中的说明[^2]。 #### 2. **信号与槽机制** 在Qt中,事件处理主要依赖于信号(Signal)和槽(Slot)机制。当用户点击某个按钮时,会产生相应的信号;程序接收到此信号后执行特定的操作(即调用对应的Slot函数)。例如按下“+”号按钮,则触发加法操作准备阶段。 ```cpp connect(ui->btnAdd, &QPushButton::clicked, this, &Calculator::onOperatorClicked); ``` 上述代码片段展示了如何连接按钮(`ui->btnAdd`)被点击产生的信号至处理器方法(`&Calculator::onOperatorClicked`)之中[^4]。 #### 3. **数值存储与计算流程管理** 为了支持连续多次计算而不仅仅是单一表达式的求解过程,需定义几个变量用来保存中间状态数据: - `double num1`: 存储第一个操作数。 - `QString operatorStr`: 记录所选运算符。 - 布尔型标志位判断是否刚完成一次完整的计算动作以便重置新输入序列起点位置等控制逻辑需求。 每当用户选择了新的运算符之前如果已经有待处理的数据存在的话就立即先做之前的那步运算再更新最新录入的信息作为下一个参与项对待[^3]。 #### 4. **中缀转后缀表达式解析**(针对更复杂情况下的扩展考虑) 虽然题目描述仅涉及基础二元运算场景无需特别关注复杂的语法分析环节但如果未来打算增加更多高级特性比如括弧嵌套或者多层混合优先级规则那么就需要引入专门的技术手段解决这一难题——即将原始输入字符串形式转化为计算机易于理解和快速执行的标准内部表示方式之一便是所谓的逆波兰记法(Postfix Notation)。 这里简单列举一下转换原则: - 遇见数字直接加入输出队列; - 当遇到左圆括号 "(" ,将其压入栈顶直到匹配右半部分 ")" 出现为止期间保持原样复制到目标区域同时弹出所有位于两者之间的符号并依次追加到最终成果集里最后丢弃这对边界标记本身不再保留; - 对于其余各类常规操作码而言遵循各自固有的权重关系决定何时应该立即将之移交给下游还是暂时搁置等待后续条件满足后再行动等等细节均已在参考资料中有详尽阐述可供查阅学习。 --- ### 示例代码 下面给出一段简化版的核心业务逻辑伪代码供参考理解整体架构: ```cpp void Calculator::onNumberButtonClicked() { QString currentText = ui->display->text(); QPushButton *button = qobject_cast<QPushButton*>(sender()); if (!currentText.isEmpty()) { ui->display->setText(currentText.append(button->text())); } else { ui->display->setText(button->text()); } } void Calculator::onOperatorClicked() { double currentValue; bool ok; currentValue = ui->display->text().toDouble(&ok); if(ok){ if(!operatorStr.isEmpty()){ calculateResult(); // Perform previous operation first. } num1 = currentValue; operatorStr = sender()->objectName(); ui->display->clear(); } } // Function to perform actual calculation based on stored values and selected operator. void Calculator::calculateResult(){ double resultValue; double secondOperand = ui->display->text().toDouble(); if(operatorStr == "+") {resultValue=num1+secondOperand;} else if(operatorStr=="-"){resultValue=num1-secondOperand;} else if(operatorStr=="*"){resultValue=num1*secondOperand;} else if(operatorStr=="/"){ if(secondOperand !=0){resultValue=num1/secondOperand;} else{return;} // Handle division by zero error silently here or show message box etc.. } ui->display->setNum(resultValue); operatorStr.clear(); } ``` --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值