Qt :Créez un QItemDelegate pour avoir un éditeur personnalisé (zones de liste déroulante) dans un QTableView avec QStandardItemModel

StackOverflow https://stackoverflow.com//questions/9672158

Question

Je dois implémenter une table dans Qt qui affiche une zone de liste déroulante sur chaque ligne d'une colonne particulière.

Jusqu'à présent, sur la base de cet exemple :http://doc.qt.nokia.com/4.7-snapshot/itemviews-spinboxdelegate.htmlet sur cette question :QStandardItem + QComboBoxJ'ai réussi à créer un QItemDelegate.

Mon problème est que tout fonctionne bien si je l'implémente à partir de ma fonction main() dans main.cpp, mais cela ne fonctionne pas bien si j'insère la table dans Qt Designer pour l'utiliser ensuite dans une fonction de la classe MainWindow dans mainwindow.cpp .

Pourriez-vous s'il vous plaît me donner un indice ?Merci d'avance!

Délégation sur main.cpp (ça marche bien, quand je double-clique sur la deuxième colonne ça affiche une Combo Box) :

QStandardItemModel model(4, 2);
QTableView tableView;
tableView.setModel(&model);
ComboBoxDelegate delegate;
tableView.setItemDelegateForColumn(1,&delegate);
tableView.horizontalHeader()->setStretchLastSection(true);

for (int row = 0 ; row < 4; ++row) {
    for (int col = 0; col < 2; ++col) {
        QModelIndex index = model.index(row, col, QModelIndex());
        model.setData(index, QVariant((row+1) * (col+1)));
    }
}
tableView.show();

Délégation sur mainwindow.cpp alternative 1 (elle affiche une table vide)

QStandardItemModel model(4,2);
ui->tablePoint->setModel(&model);
ComboBoxDelegate delegate;
ui->tablePoint->setItemDelegateForColumn(1,&delegate);
ui->tablePoint->horizontalHeader()->setStretchLastSection(true);

for (int row = 0 ; row < 4; ++row) {
    for (int col = 0; col < 2; ++col) {
        QModelIndex index = model.index(row, col, QModelIndex());
        model.setData(index, QVariant((row+1) * (col+1)));
    }
}

Délégation sur l'alternative 2 de mainwindow.cpp (elle affiche le tableau mais lorsque je double-clique sur la deuxième colonne, elle n'affiche pas la zone de liste déroulante.Au lieu de cela, il affiche la Spin Box normale :

QStandardItemModel* model = new QStandardItemModel(4,2);
ui->tablePoint->setModel(model);
ComboBoxDelegate delegate;
ui->tablePoint->setItemDelegateForColumn(1,&delegate);
ui->tablePoint->horizontalHeader()->setStretchLastSection(true);

for (int row = 0 ; row < 4; ++row) {
    for (int col = 0; col < 2; ++col) {
        QModelIndex index = model->index(row, col, QModelIndex());
        model->setData(index, QVariant((row+1) * (col+1)));
    }
}
Était-ce utile?

La solution

En supposant que dans les deux cas mainwindow.cpp, le code que vous affichez est dans le constructeur, vous faites l'erreur classique "venant de java, python, perl ou de tout autre langage où vous ne vous souciez pas de la gestion de la mémoire" pour allouer votre modèle et/ou déléguer sur la pile plutôt que sur le tas.

En C++, les éléments alloués sur la pile (par ex. QStandardItemModel model(4,2);) est détruit au retour de la fonction, tandis que les éléments alloués sur le tas (par ex. QStandardItemModel* model = new QStandardItemModel(4,2); vit jusqu'à ce que tu delete il).Le cas 1 fonctionne car les éléments alloués sur la pile dans main() vit pendant toute la durée de l'application.

Conclusion :pour le cas 3, faites un ComboBoxDelegate* delegate = new ComboBoxDelegate(); et ui->tablePoint->setItemDelegateForColumn(1,delegate);

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top