Qt-在QSignalMapper调用的函数中更新
Qt - Updating in the function called by QSignalMapper
我有一个QTreeWidget,其中每个项在一列中都有一个QComboBox。我已经用QSignalMapper将它连接到一个插槽,当它被触发时,我成功地检索了组合框中的项和索引。我是这样做的:
foreach(Workplace *wp, allWorkplaces){
QTreeWidgetItem *workplaceItem = new QTreeWidgetItem;
workplaceItem->setText(0, wp->workplaceName());
workplaceItem->setText(1, wp->workplaceDescription());
myWorkplaceUi->treeWidget->addTopLevelItem(workplaceItem);
QComboBox *combo = new QComboBox();
combo->addItems(allShiftModels);
combo->setAutoFillBackground(true);
ShiftModel *shiftModel = qobject_cast<ShiftModel *>(wp->usedShiftModel);
myWorkplaceUi->treeWidget->setItemWidget(workplaceItem,2, combo);
if(shiftModel && !shiftModel->shiftModelName().isEmpty()){
qDebug()<<"after the cast: "<< shiftModel->shiftModelName();
combo->setCurrentIndex(combo->findText(shiftModel->shiftModelName(), Qt::MatchExactly));
}else{
combo->setCurrentIndex(combo->findText("None", Qt::MatchExactly));
}
connect(combo, SIGNAL(currentIndexChanged(int)), signalMapper, SLOT(map()));
signalMapper->setMapping(combo, QString("%1").arg(wp->workplaceName()));
}
connect(signalMapper, SIGNAL(mapped(const QString &)),this, SLOT(changed(const QString &)));
我的目标是,在检索Workplace
和ShiftModel
之后,在我已经创建的Workplaces的实例中更新它们。所以,基本上,我试图找到所选的Workplace和ShiftModel,因为根据所选的ShiftModel的不同,我会在Workplace类中更改指向ShiftModel:
class Workplace : public QObject
{
Q_OBJECT
public:
(...)
ShiftModel *usedShiftModel;
(...)
}
和changed
插槽:
void workplacesdialog::changed(QString position){
QList<Workplace* > allWorkplaces = this->myProject->listMyWorkplaces();
QList<ShiftModel*> allShiftModels = this->myProject->myFactory->listShiftModels();
foreach(Workplace* workplace, allWorkplaces){
foreach(ShiftModel *shiftmodel, allShiftModels){
qDebug() <<"workplace:"<< workplace->workplaceName();
qDebug() <<"shiftmodel:"<< shiftmodel->shiftModelName();
QString wp = position;
QTreeWidgetItem* item=(QTreeWidgetItem*)myWorkplaceUi->treeWidget->findItems(wp,Qt::MatchExactly,0).at(0);
QComboBox *combo = (QComboBox*)myWorkplaceUi->treeWidget->itemWidget(item,2);
if(combo && item){
QString sm = combo->currentText();
qDebug() << "selected shiftmodel "<< sm << " on workplace "<< wp;
if(workplace->workplaceName()==wp && shiftmodel->shiftModelName()==sm){
workplace->usedShiftModel = shiftmodel;
break;
}
else{
workplace->usedShiftModel = 0;
return;
}
}else{
qDebug() << "cast failed!";
return;
}
}
}
}
因此,我的问题是,当我单击其中一个组合框时,成功地检索到所选的项目和索引,但当我尝试用插槽中的两个foreach
循环遍历它们时,它并没有像我预期的那样工作。我希望每次我点击其中一个组合框中的索引时,都会调用它,事实确实如此。尽管出于某种原因,我用来将用户选择的内容与已经安装的内容相匹配的方法不起作用。
此外,它似乎只命中allWorkplaces
列表上的第一个workplace
和ShiftModels
列表上的第1个shiftmodel
,这是我的问题。
如果有人知道如何解决这个问题,或者有任何想法可以分享,请告诉我。非常感谢。
问题是:
if(workplace->workplaceName()==wp && shiftmodel->shiftModelName()==sm){
workplace->usedShiftModel = shiftmodel;
break;
}
else{
workplace->usedShiftModel = 0;
return;
}
如果工作场所名称不匹配或轮班模型名称不匹配,则工作场所与其当前链接的轮班模型之间的关系将被删除,函数将返回。
我可以为您重组两个for循环,但有一种更简单、更不容易出错的方法:
注意:我用"TODO"标记了一些代码路径,由于时间不够,我跳过了这些路径。不过,你应该能够自己弄清楚
// Set up hashes for quick lookup
QHash< QString, Workplace* > workplaceHash;
QList<Workplace* > allWorkplaces = this->myProject->listMyWorkplaces();
foreach( Workplace* workplace, allWorkplaces )
{
workplaceHash.insert( workplace, workplace->workplaceName() );
}
// TODO: Do a similar thing for the shift models here
// Find the selected workplace
if( !workplaceHash.contains( position ) )
{
// TODO: Error handling (An unknown/No workplace was selected)
return;
}
// else: A valid workplace was selected
Workplace* selectedWorkplace = workplaceHash.value( position );
// TODO: Retrieve the name of the shift model (stored in variable sm)
// Find the selected shiftmodel
if( !shiftplaceHash.contains( sm ) )
{
// No shift model was selected
selectedWorkplace->usedShiftModel= 0;
return;
}
// Else: Both work place and shift model were selected
Shiftplace* selectedShiftModel = shiftplaceHash.value( sm );
selectedWorkplace->usedShiftModel = selectedShiftModel;
重构的几个想法:
- 您可以在这个方法之外创建散列,并将它们存储在成员变量中。只要确保在添加或删除工作区时始终更新哈希即可
- 通过将代码的部分提取到单独的方法中,例如
QString getSelectedShiftModelName()
等,可以更容易地发现错误
所以,最后我发现我的循环真的一团糟。。。这现在正在工作:
void workplacesdialog::changed(QString position){
QList<Workplace* > allWorkplaces = this->myProject->listMyWorkplaces();
QList<ShiftModel*> allShiftModels = this->myProject->myFactory->listShiftModels();
qDebug() << allWorkplaces.size() << " workplaces";
qDebug() << allShiftModels.size() << " ShiftModels";
QString wp = position;
QString sm;
QTreeWidgetItem* item=(QTreeWidgetItem*)myWorkplaceUi->treeWidget->findItems(wp,Qt::MatchExactly,0).at(0);
QComboBox *combo = (QComboBox*)myWorkplaceUi->treeWidget->itemWidget(item,2);
if(combo && item){
sm = combo->currentText();
qDebug() << "selected shiftmodel "<< sm << " on workplace "<< wp;
}else{
qDebug() << "cast failed!";
return;
}
foreach(Workplace* workplace, allWorkplaces){
foreach(ShiftModel *shiftmodel, allShiftModels){
qDebug() <<"workplace:"<< workplace->workplaceName();
qDebug() <<"shiftmodel:"<< shiftmodel->shiftModelName();
if(workplace->workplaceName()==wp && shiftmodel->shiftModelName()==sm){
qDebug() << "found match!: "<< wp << " >>>>> " << sm;
workplace->usedShiftModel = shiftmodel;
return;
}else if(workplace->workplaceName()==wp && sm=="None"){
qDebug() << "clear match: "<< wp << " >>>>> " << sm;
workplace->usedShiftModel = 0;
return;
}
}
}
}
- 指针没有更新它在void函数内部指向的值
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 尝试使用 EvtSetChannelConfigProperty() 函数更新最大事件日志文件大小时插入的错误值
- 如何更新传递到函数中的数组
- 空递归函数的更新
- 如何获取从C++发送到Lua函数的表的更新值?
- 在构造函数中更新指针向量时出现问题
- 在函数中删除第一个元素后,如何更新链接列表的phead
- 更新函数之间精灵的位置
- 为什么我的函数只在我用 & 符号传递结构时才更新结构?
- C++:使用父类运算符函数更新子类对象的继承变量
- 构造函数不更新类成员变量
- 如何每秒调用更新Qt小部件的函数
- 通过引用传递 std::string 不会更新调用函数中的字符串值
- C++ 链表 - 插入节点函数不会更新函数范围之外的值
- 从函数更新(覆盖)和显示数组
- 当其他函数更新到库中时,不会加载加载库
- 如何使用 C++ 中的函数更新结构的值
- C++使用set函数更新对象属性
- 我的函数更新恒星附近行星的位置有什么问题?