Вопрос:Создайте QItemDelegate, чтобы иметь собственный редактор (поля со списком) в QTableView с помощью QStandardItemModel.
-
12-12-2019 - |
Вопрос
Мне нужно реализовать таблицу в Qt, которая отображает поле со списком в каждой строке определенного столбца.
Пока что на основе этого примера:http://doc.qt.nokia.com/4.7-snapshot/itemviews-spinboxdelegate.htmlи по этому вопросу:QStandardItem + QComboBoxМне успешно удалось создать QItemDelegate.
Моя проблема в том, что все работает нормально, если я реализую это из своей функции main() в main.cpp, но это не работает, если я вставляю таблицу в Qt Designer, чтобы использовать ее затем в функции класса MainWindow в mainwindow.cpp. .
Не могли бы вы дать мне подсказку?Заранее спасибо!
Делегирование в main.cpp (работает хорошо, когда я дважды щелкаю второй столбец, появляется поле со списком):
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();
Делегирование в mainwindow.cpp, альтернатива 1 (показывает пустую таблицу)
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)));
}
}
Делегирование в альтернативе 2 mainwindow.cpp (она показывает таблицу, но когда я дважды щелкаю второй столбец, поле со списком не отображается.Вместо этого отображается обычное поле счетчика):
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)));
}
}
Решение
Предполагая, что в обоих случаях mainwindow.cpp код, который вы показываете, находится в конструкторе, вы выполняете классическую ошибку «из Java, Python, Perl или любого другого языка, где вам наплевать на управление памятью», чтобы выделить вашу модель и/или делегировать в стеке, а не в куче.
В C++ данные, размещенные в стеке (например, QStandardItemModel model(4,2);
) уничтожается при возврате из функции, а материал, размещенный в куче (например, QStandardItemModel* model = new QStandardItemModel(4,2);
живет, пока ты delete
это).Случай 1 работает, потому что данные, размещенные в стеке в main()
живет на протяжении всего времени работы приложения.
Нижняя граница:для случая 3 сделайте ComboBoxDelegate* delegate = new ComboBoxDelegate();
и ui->tablePoint->setItemDelegateForColumn(1,delegate);