一、简化重复结构的信号槽连接
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()
槽函数中使用这个映射来执行相应的操作。这种方法将逻辑与操作进行了分离,让代码看起来更加整洁和美观。