Qt:Crie um QItemDelegate para ter um editor customizado (Combo Boxes) em um QTableView com QStandardItemModel
-
12-12-2019 - |
Pergunta
Preciso implementar uma tabela no Qt que mostre uma caixa de combinação em cada linha de uma coluna específica.
Até agora com base neste exemplo:http://doc.qt.nokia.com/4.7-snapshot/itemviews-spinboxdelegate.htmle nesta questão:QStandardItem + QComboBoxConsegui criar um QItemDelegate com sucesso.
Meu problema é que tudo funciona bem se eu implementar a partir da minha função main() em main.cpp, mas não funciona bem se eu inserir a tabela no Qt Designer para usá-la dentro de uma função da classe MainWindow em mainwindow.cpp .
Você poderia me dar uma pista?Desde já, obrigado!
Delegação em main.cpp (funciona bem, quando clico duas vezes na segunda coluna mostra uma 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();
Delegação em mainwindow.cpp alternativa 1 (mostra uma tabela vazia)
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)));
}
}
Delegação em mainwindow.cpp alternativa 2 (mostra a tabela mas quando clico duas vezes na segunda coluna não mostra o Combo Box.Em vez disso, mostra a Spin Box normal):
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)));
}
}
Solução
Supondo que em ambos os casos mainwindow.cpp o código que você mostra está no construtor, você faz o clássico erro "vindo de java, python, perl ou qualquer linguagem onde você não dá a mínima para gerenciamento de memória" para alocar seu modelo e/ou delegar na pilha em vez de na pilha.
Em c++, coisas alocadas na pilha (por exemplo QStandardItemModel model(4,2);
) é destruído ao retornar da função, enquanto o material alocado no heap (por exemplo QStandardItemModel* model = new QStandardItemModel(4,2);
vive até você delete
isto).O caso 1 funciona porque o material alocado na pilha em main()
vive durante a duração do aplicativo.
Conclusão:para o caso 3, faça um ComboBoxDelegate* delegate = new ComboBoxDelegate();
e ui->tablePoint->setItemDelegateForColumn(1,delegate);