Qt - 在QSignalMapper调用的函数中更新

时间:2013-09-02 12:57:50

标签: c++ qt pointers signals-slots qcombobox

我有一个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 &)));

我的目标是,在检索WorkplaceShiftModel之后,在我已创建的工作场所的实例中更新它们。所以,基本上,我尝试找到所选的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循环遍历它们时,它不像我预期的那样工作。我希望每次点击其中一个组合框中的索引时,都会调用它,它就是。虽然,由于某种原因,我用来匹配用户选择的方法与已经实例化的方法不起作用。

此外,它似乎只会点击workplace列表中的第一个allWorkplaces以及shiftmodel列表中的第一个ShiftModels,这是我的问题

如果有人知道如何解决此问题或有任何想法分享,请告诉我们。谢谢。

2 个答案:

答案 0 :(得分:1)

问题在于:

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()等。

答案 1 :(得分:1)

所以,最后我发现我的循环真的搞砸了......现在正在运作:

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;
            }
        }
    }
}