Использование QWidget в Qt View - PullRequest
4 голосов
/ 03 марта 2011

Проблема: у меня есть простая QStringListModel, которую я хочу отобразить в виде. Однако я хочу, чтобы каждый элемент в представлении был пользовательским QWidget, который я создал. Я не понимаю, почему это такая сложная проблема! Я искал в Интернете решения, и, хотя я нахожу кусочки здесь и там, ни одно хорошее решение не отвечает всем моим потребностям.

Основной код для настройки моей модели / вида:


QStringList strings;
// add some strings to the model

QStringListModel* model = new QStringListModel(strings);
QListView* view = new QListView;

view->setModel(model);


Я пробовал разные попытки сделать это безрезультатно.

Попытка # 1

Я попытался создать подкласс нового объекта QItemDelegate. Внутри этого объекта я переопределил методы создания редактора. Я выполнил все шаги по настройке этого делегата. Проблема состоит в том, что когда представление заполняется моделью, оно захватывает каждый элемент в модели в Qt :: DisplayRole, когда мне нужно, чтобы захватить каждый элемент в Qt :: EditRole.

Попытка № 2

Другой метод, который я попробовал, заключался в создании подкласса QListView и переопределении метода setModel для вызова setIndexWidget для каждого элемента в модели. Мой код выглядит примерно так:


void CustomListView::setModel(QAbstractItemModel* model)
{
    QListView::setModel(model);

    for (int i = 0; i rowCount(); ++i)
    {
        QModelIndex index = model->index(i, 0);

        CustomWidget* widget = new CustomWidget;
        setIndexWidget(index, widget);
    }
}

Это сработало, если добавить мой объект CustomWidget к каждой строке в представлении списка. Чтобы гарантировать, что обычные данные модели также не отображаются под моими объектами CustomWidget, я также переопределил CustomListView :: paintEvent (событие QPaintEvent *), чтобы ничего не делать. Опять же, это сработало.

Но моя главная проблема сейчас заключается в том, что при отображении списка, хотя мои CustomWidget отображаются на нем правильно, фон списка имеет сплошной белый цвет. Я попытался вызвать setAutoFillBackground (false) для CustomListView, но это ничего не сделало. Я хочу, чтобы у моего списка был прозрачный фон.

Любая обратная связь по этой проблеме будет очень приветствуется. Я потратил много времени, пытаясь заставить это работать! Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 апреля 2011

Я предлагаю придерживаться делегатов с пользовательской окраской.

См. Пример звездного делегата Вот так вы рисуете (см. Ниже) так, как хотите, а затем редактируете с помощью createEditorкогда вы получаете фокус.

void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
 {
     if (qVariantCanConvert<StarRating>(index.data())) {
         StarRating starRating = qVariantValue<StarRating>(index.data());

         if (option.state & QStyle::State_Selected)
             painter->fillRect(option.rect, option.palette.highlight());

         starRating.paint(painter, option.rect, option.palette,
                          StarRating::ReadOnly);
     } else {
         QStyledItemDelegate::paint(painter, option, index);
     }
 }

Подвох или чит в том, что вы можете рисовать свой виджет без создания экземпляра редактора или когда ваш виджет находится в режиме редактирования используя drawControl().См код краски в этот вопрос.

0 голосов
/ 11 апреля 2011

Я думаю, что у меня была похожая проблема для рендеринга пользовательских данных в QStandardItemModel.Чтобы решить эту проблему, я создал собственный QStyledItemDelegate.В методе createEditor вы можете проверить:

if( qVariantCanConvert<YourObject>(index.data(Qt::YourRole)) )

Затем создайте свой редактор, который на самом деле является нужным вам виджетом.И установите его значение с данными из вашей модели.Для настройки своего виджета я использовал таблицы стилей, такие как CustomWidget.setStylesheet ("background: blue");

В методе рисования вашего делегата, если вы хотите тот же виджет, который вы делаете точно так же, как вы сделали с редактором.

CustomWidget renderer;
renderer.setText( index.data(Qt::DisplayRole).toString() );
renderer.resize(option.rect.size());
painter->save();
painter->translate(option.rect.topLeft());
renderer.render(painter);
painter->restore();

Вам придется самостоятельно обращаться с openPersistentEditor и closePersistentEditor.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...