Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > в QtreeWidget не отображается делегат QComboBox


Автор: daemonaz 3.10.2014, 08:59
Уважаемые!
Прошу помочь разобраться проблему с делегатом, бьюсь как об стену, не могу понять почему в QTreeWidget не отображается делегат?
До этого использовал функцию setItemWidget, где создаю объект QComboBox и вставляю в ячейку, теперь ставится вопрос о создании делегата.

Вот мой код делегата

Код

#include <QComboBox>
#include "mycomboboxdelegate.h"

MyComboBoxDelegate::MyComboBoxDelegate(QObject *parent) :
    QItemDelegate(parent)
{
    // Object for calculate of editor size for some GUI themes
   QComboBox *editor = new QComboBox(static_cast<QWidget*>(parent));
   editor->setFrame(false);
   editor->adjustSize();
   editorSize = QSize(100,editor->height()*0.9);
   delete editor;

   //this->list=iList;
}

QWidget * MyComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    QComboBox *editor = new QComboBox(parent);
    QStringList list ;
    list << "a" << "b" << "c" << "d";
    editor->setEditable(true);
    editor->addItems(list);
    return editor;
}

void MyComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    comboBox->setCurrentIndex(comboBox->findData(value,Qt::EditRole,Qt::MatchExactly));
    comboBox->addItem(value);
}

void MyComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const
{
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    QString value = comboBox->currentText();
    model->setData(index, value);
}

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

QSize MyComboBoxDelegate::sizeHint ( const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
    return editorSize;
}


код где создается объект делегата и вставляем в дерево в конструкторе MainWindow

Код


    QTreeWidget *tw =  new QTreeWidget(this);
    MyComboBoxDelegate *cb = new MyComboBoxDelegate(tw);

    tw->setHeaderLabels(QStringList() <<
                                      tr("1 столбец") <<
                                      tr("2 стобец") <<
                                      tr("3 столбец"));

    tw->addTopLevelItem(new QTreeWidgetItem(QStringList() << "aa" << ""));
    tw->setItemDelegateForColumn(1, cb);



вместо комбобокса отображается выделенный кубик, как заставить отображать в ячейке комбобокс?
буду признателен за любую помощь.

Автор: math64 6.10.2014, 07:58
Зачем это?
Цитата(daemonaz @  3.10.2014,  08:59 Найти цитируемый пост)
Код

MyComboBoxDelegate::MyComboBoxDelegate(QObject *parent) :
    QItemDelegate(parent)
{
    // Object for calculate of editor size for some GUI themes
   QComboBox *editor = new QComboBox(static_cast<QWidget*>(parent));
   editor->setFrame(false);
   editor->adjustSize();
   editorSize = QSize(100,editor->height()*0.9);
   delete editor;
   //this->list=iList;
}


Код

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


Автор: daemonaz 6.10.2014, 08:18
math64, это устанавливает фиксированный размер комбобокса, просто шаг отчаяния, нашел в инете и вставил туда кусок кода, но не пашет, если даже уберу эти куски, все равно не пашет, не отображается комбобокс, почему?

Автор: math64 6.10.2014, 08:27
Размер редактора задается в updateEditorGeometry(). Можно установить в option.rect, можно поменять на свой.
sizeHint() не нужен вовсе.
Кстати, QStringList проще создавать так:
Код

tr("1 столбец,2 стобец,3 столбец").split(',');

Автор: daemonaz 6.10.2014, 08:46
math64, это я знаю, спасибо за подсказки, очень полезно. Но мне надо хотя бы показать комбобокс, не смогли бы у себя создать простенький проектик с делегатом, почему-то в упор не хочет отображаться, вместо комбобокса отображается выделенный прямоугольник.

Автор: math64 6.10.2014, 10:18
Код

#include <QtGui/QApplication>
#include <QtGui/QTreeWidget>
#include <QtGui/QTreeWidgetItem>
#include <QtGui/QStyledItemDelegate>
#include <QtGui/QComboBox>

class MyDelegate : public QStyledItemDelegate
{
public:
    explicit MyDelegate(QObject* parent = NULL) : QStyledItemDelegate (parent) {}
    virtual ~MyDelegate() {}
    virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        QComboBox* editor = new QComboBox(parent);
        editor->addItems(tr("item1,item2,item3,item4,item5").split(','));
        editor->setEditable(true);
        return editor;
    }
    virtual void setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QComboBox* cb = (QComboBox*)editor;
        cb->setEditText(index.model()->data(index, Qt::EditRole).toString());
    }
    virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        QComboBox* cb = (QComboBox*)editor;
        QString value = cb->currentText();
        model->setData(index, value);
    }
    virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        editor->setGeometry(option.rect);
    }
};

int main(int argc, char** argv)
{
  QApplication app(argc, argv);
  QTreeWidget tree;
  QTreeWidgetItem* item1 = new QTreeWidgetItem(&tree, QStringList("item1") );
  item1->setFlags(item1->flags() | Qt::ItemIsEditable);
  QTreeWidgetItem* item2 = new QTreeWidgetItem(item1, QStringList("item2") ) ;
  item2->setFlags(item2->flags() | Qt::ItemIsEditable);
  QTreeWidgetItem* item3 = new QTreeWidgetItem(item2, QStringList("item3") );
  item3->setFlags(item3->flags() | Qt::ItemIsEditable);
  QTreeWidgetItem* item4 = new QTreeWidgetItem(&tree, QStringList("item4") );
  item4->setFlags(item4->flags() | Qt::ItemIsEditable);
  QTreeWidgetItem* item5 = new QTreeWidgetItem(item4, QStringList("item5") );
  item5->setFlags(item5->flags() | Qt::ItemIsEditable);
  tree.setItemDelegate(new MyDelegate(&tree));
  tree.setEditTriggers(QTreeWidget::AllEditTriggers);
  tree.show();
  app.exec();
}

Все вероятно из-за отсутствия этого:
Код

  item1->setFlags(item1->flags() | Qt::ItemIsEditable);

Автор: daemonaz 6.10.2014, 10:24
math64, спасибо! заработало!!  smile  Не смог догадаться что дело в свойствах итема. smile 
но отображается тогда когда щелкну по ячейке мышью в режиме редактирования, а как сделать чтобы постоянно отображался?

Автор: math64 6.10.2014, 10:32
нафиг нужно?
Если фсё-таки нужно, переопределяй
Код

paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

создавай в нём временный QComboBox рисуй как его в ячейке.

Автор: daemonaz 6.10.2014, 10:37
math64, спасибо тебе, добрый человек!  smile 
На случай если свыше команда придет, чтобы был постоянно нарисован комбобокс, а так конечно красивей будет без него, кому надо, пусть и щелкает.  smile 

Автор: math64 6.10.2014, 10:53
Ну едиственное исключение: когда в комбо-боксе два значения (true/false), его лучше заменить на чекбокс. Вот его-то действительно лучше показывать всегда.

Автор: daemonaz 6.10.2014, 11:18
math64, понял, спасибо!
Но я так понял что его имеет смысл использовать в модели-вид, а в обычном QTreeWidget есть же setChecked() который показывает галочку, но вот вопрос, у меня галочка постоянно находится с краю слева, как передвинуть в центр ячейки? Там можно только текст передвигать

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)