2013-09-02 2 views
1

각 항목에 QComboBox가있는 QTreeWidget이 있습니다. 나는 그것을 QSignalMapper로 슬롯에 연결했고, 트리거되었을 때 콤보 박스에서 아이템과 인덱스를 성공적으로 검색하고있다. 나는 이런 식으로했다 :Qt - 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를 검색 한 후, 내 이미 생성 된 사업장의 경우에을 업데이트 할 수 있습니다.

class Workplace : public QObject 
{ 
    Q_OBJECT 

public: 
    (...) 
    ShiftModel *usedShiftModel; 
    (...) 
} 

그리고 changed 슬롯 : 그래서, 기본적으로 내가 선택한 ShiftModel에 따라, 나는 직장 클래스의 ShiftModel에 대한 포인터를 변경하기 때문에, 직장 및 선정 된 ShiftModel를 찾아보십시오

내가 슬롯에 두 foreach 루프로를 통과 할 때
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; 
      } 
     } 
    } 
} 

그래서,이 내 문제는, 때, 다음을 I 성공적으로 콤보 중 하나를 클릭하여 선택한 항목과 색인을 모두 검색하지만, 내가 기대했던대로 작동하지 않는다. 나는 콤보 박스 중 하나에서 색인을 클릭 할 때마다 이것이 호출 될 것이라고 기대했다. 어떤 이유로 사용자가 선택한 것을 이미 시작한 것과 일치시키기 위해 사용하는 방법이 작동하지 않습니다. 그것은 단지 명중 모두 allWorkplaces 목록뿐만 아니라 ShiftModels 목록 1 shiftmodel에 1 workplace, 이것은 내 문제처럼

또한, 보인다.

누구든지이 문제를 해결하는 방법을 알고 있거나 공유 할 아이디어가 있으면 알려 주시기 바랍니다. 고맙습니다.

답변

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

문제는 이것이다 : 직장 이름이 일치하지 않거나 변속 모델 이름이 일치하지 않는 두 경우 작업 장소와 현재 연결된 시프트 모델 사이의 관계가

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

을 제거하고 당신의 함수가 반환됩니다.

나는 당신을 위해 두-루프를 재구성 할 수 있지만 더 쉽고 덜 오류가 발생하기 쉬운 방법이있다 :

참고 : 나는 생략 "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()
+0

이 정말 똑똑 소리, 그리고 어쩌면 그래도 난 다른 해결책 ... 좋은 팁을 가지고 내가 빠른 프로토 타이핑을위한 지금 당장에 복귀 하겠지만, 길 아래에 어떤 시점이 지금 노력하고 있습니다! +1했습니다. – Joum

관련 문제