crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Делегат QComboBox в модели QTableView, Как выводить делегат в таблице?
Jafferson
  опции профиля:
сообщение 23.11.2018, 8:19
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 1
Регистрация: 23.11.2018
Пользователь №: 5011

Спасибо сказали: 0 раз(а)




Репутация:   0  


Добрый день товарищи. Появилась проблема которую не могу решить уже очень долгое время. В общем, у меня есть модель QTableView в которой я хочу в определенном столбце выводить делегат QComboBox. Проблема в том, что не понимаю что нужно возвращать в методе data в столбце где должен быть делегат. Подскажите, что я делаю не так. P.S. Это мой первый большой проект на Qt, так что принимаю любую критику.

Описание делегата.
void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyledItemDelegate::paint(painter, option, index);
}

QWidget *MyDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{    
    if (index.column() == 2)
    {
        QComboBox *comboBox = new QComboBox(parent);
        comboBox->addItems(m_list);
        return comboBox;
    }
    else
    {
        return QStyledItemDelegate::createEditor(parent, option, index);
    }

}

void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if (index.column() == 2)
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        int pos = comboBox->findText(index.model()->data(index, Qt::EditRole).toString(), Qt::MatchExactly);
        comboBox->setCurrentIndex(pos);
    }
    else
    {
        return QStyledItemDelegate::setEditorData(editor, index);
    }
}

void MyDelegate::setModelData( QWidget * editor, QAbstractItemModel *model, const QModelIndex& index) const
{
    if (index.column() == 2)
    {
        QComboBox *comboBox = static_cast<QComboBox*>(editor);
        QString data = comboBox->currentText();
        model->setData(index, data);
    }
    else
    {
        return QStyledItemDelegate::setModelData(editor, model, index);
    }
}

void MyDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
    editor->setGeometry(option.rect);
}


Слот, который создает новую заметку в таблице.
bool MainWindow::addDiscip()
{
    if (!isTableOpen())
    {
        QMessageBox::warning(this, "Внимание", tr("Таблица не открыта!"));
        return false;
    }

    AddDiscipDialog discipDlg(this);
    discipDlg.setWindowTitle("Дисциплины");
    MyDelegate *delegate = new MyDelegate(this);
    Note note;  // объект который содержит в себе информацию: название, номер семестра, номер курса дисциплины
    discipDlg.setNote(&note);
    discipDlg.setDelegate(delegate);
    if (discipDlg.exec() != AddDiscipDialog::Accepted)
    {
        return false;
    }

    maintable->insert(note);
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui->tableView->setItemDelegateForColumn(2, delegate);
    return true;
}


Метод data моей модели.
QVariant MainTable::data(const QModelIndex &index, int role) const
{
    if (role == Qt::DisplayRole)
            switch (index.column())
            {
            case 0:
                return mMainTable[index.row()].discipname();
            case 1:
                return mMainTable[index.row()].discipcourse();
            case 2:
                return ???
            }

    return QVariant();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 24.11.2018, 8:15
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2886
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


наверное, ничего не надо там возвращать, если делегат есть. Виджет же сам себя отображает. Либо нужно вызвать data родительского класса (попробовать сейчас не на чем)

Cовет: нумеровать колонки не цифрами, а именованными константами
например

enum class mycolumns:int
{
   discipname=0,
   discipcourse,
   somedata,
};

...

switch (mycolumns(index.column()))
{
            case mycolumns::discipname:
                return mMainTable[index.row()].discipname();

            case mycolumns::discipcourse:
                return mMainTable[index.row()].discipcourse();

            case mycolumns::somedata:
                return QVariant();
  }


Сообщение отредактировал Алексей1153 - 24.11.2018, 8:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 11.12.2018, 13:28
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Алексей1153 @ 24.11.2018, 10:15) *
наверное, ничего не надо там возвращать, если делегат есть.
возвращать всё же стоит. Для EditRole при наличии своего делегата можно возвращать тоже что и для DisplayRole (т.е. для обычного отображения).


Цитата(Jafferson @ 23.11.2018, 10:19) *
Слот, который создает новую заметку в таблице.
Проблемы: каждый раз когда будет вызван слот будет создан новый делегат, помещён в представление. А старый так и останется занимать память.
Правильный способ: создал представление, создал ему делегаты. Делегаты должны сами получать связанные с их работой данные.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 19.10.2019, 1:10