1

各項目の列に QComboBox がある QTreeWidget があります。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;
            }
        }
    }
}

したがって、これに関する私の問題は、コンボボックスの1つをクリックすると、選択されたアイテムとインデックスの両方を正常に取得できforeachますが、スロット内の2つのループでそれらをトラバースしようとすると、期待どおりに機能しません。コンボボックスのいずれかでインデックスをクリックするたびに、これが呼び出されることを望んでいました。ただし、何らかの理由で、ユーザーが選択したものと既に設定されているものを一致させるために使用している方法は機能しません。

また、リストの1番目workplaceallWorkplacesリストの1番目の両方にしかヒットしないように見えますが、これは私の問題です。shiftmodelShiftModels

誰かがこれを修正する方法を知っているか、共有するアイデアを持っている場合は、私に知らせてください. ありがとうございました。

4

2 に答える 2

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;
            }
        }
    }
}
于 2013-09-02T13:50:55.487 に答える
1

問題はこれです:

if(workplace->workplaceName()==wp && shiftmodel->shiftModelName()==sm){
    workplace->usedShiftModel = shiftmodel;
    break;
}
else{
    workplace->usedShiftModel = 0;
    return;
}

職場名が一致しない場合、またはシフト モデル名が一致しない場合、職場と現在リンクされているシフト モデルとの関係が削除され、関数が戻ります。

2 つの 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()コードの一部を別のメソッドなどに抽出することで、エラーを簡単に見つけることができます。
于 2013-09-02T13:44:10.003 に答える