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


Автор: loneybibi 24.4.2011, 03:55
Есть QStringList в котором содержатся html теги вроде "<p>item 1</p>"
(вообщем текст с определенным форматированием).
Нужно их отобразить в QListWidget списке как элементы, но обработанные как
в QTextBrowser.
Сразу оговорюсь в делегатах ковыряюсь первый раз. Но все таки решил использовать
для отображения элементов именно их.

Вот создал по инструкции класс делегата на основе QItemDelegate, и второй класс
на основе QListWidget.

Возможно что то другое посоветуете! Заранее благодарю.

И сильно по возможности не ругайте! smile

Ниже проект прикрепил.

Описание класса myDelegate:
Код

class myDelegate:public QItemDelegate{
    Q_OBJECT
public:
    myDelegate(QObject *parent=0);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};


Реализация класса myDelegate:
Код

myDelegate::myDelegate(QObject *parent):QItemDelegate(parent)
{

}

QWidget *myDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
    QTextBrowser *editor=new QTextBrowser(parent);
    editor->installEventFilter(const_cast<myDelegate*>(this));
    return editor;
}

void myDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const
{
    QString value=index.model()->data(index, Qt::EditRole).toString();
    QTextBrowser *browser=static_cast<QTextBrowser*>(editor);
    browser->insertHtml(value);

}

void myDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex& index) const
{
    QTextBrowser *browser=static_cast<QTextBrowser*>(editor);
    QString value=browser->toHtml();
    model->setData(index,value);
}

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


Описание класса myList:
Код

class myList:public QListWidget{
    Q_OBJECT
public:
    myList(QWidget *parent=0);

};


Реализация класса myList:
Код

myList::myList(QWidget *parent):QListWidget(parent)
{
    myDelegate *delegate=new myDelegate(this);
    setItemDelegateForColumn(0, delegate);
}


Использую так:
Код

    QStringList itemList;
    itemList<<"<p>item1</p>";
    itemList<<"<p>item2</p>";
    myList *mainList=new myList(this);
    setCentralWidget(mainList);
    mainList->addItems(itemList);


Насколько я заметил он создает делегат и добавляет в него текст. Но как мне кажется
QTextBrowser не обрабатывает теги.

Заранее благодарю за ответы.

Автор: loneybibi 25.4.2011, 00:49
Нашел http://www.forum.crossplatform.ru/lofiversion/index.php/t2565.html статью. Вроде то что надо. на основе QTextEdit и QTextDocument. Отображает html как хотел smile
Кроме двух вещей -  теперь элементы не выделяются ни мышей , ничем что бы можно было удалить! :( И Каждый элемент занимает целую страницу, т.е. 
если элемент содержит одну строку "<p>ITEM</p>" то все окэ элементы как обычно выводятся,  а если пару таких строк то целую страницу. и потом каждый элемент на одну страницу ! Как отрисовать элемент по его размеру и как сделать возможным выделением ? 

Класс:
Код

class myDelegate:public QItemDelegate{
    Q_OBJECT
public:
    myDelegate(QObject *parent=0);
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QRectF layoutRect(const QTextDocument & td, QRect rect) const;
};


реализация:
Код

myDelegate::myDelegate(QObject *parent):QItemDelegate(parent)
{

}

void myDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QString str = index.data(Qt::DisplayRole).toString();
    QTextDocument td;
    td.setHtml(str);

    QStyleOptionViewItem opt = option;
    QRectF lr = layoutRect(td, opt.rect);

    painter->save();
    painter->translate(lr.topLeft());
    painter->setClipRect(lr.translated(-lr.x(), -lr.y()));
    td.drawContents(painter, QRectF());
    painter->restore();
}

QRectF myDelegate::layoutRect(const QTextDocument & td, QRect rect) const
{
    QRectF rectf;
    qreal xo;
    qreal yo;

    Qt::Alignment align;

    if(align & Qt::AlignLeft) {
        xo = 0;
    } else if(align & Qt::AlignRight) {
        qreal rw = td.documentLayout()->documentSize().width();
        xo = 0;
        xo = qMax((rect.width()-rw), qreal(0));
    } else if(align & Qt::AlignHCenter) {
        qreal rw = td.documentLayout()->documentSize().width();
        xo = 0;
        xo = qMax((rect.width()-rw)/2, qreal(0));
    }

    if(align & Qt::AlignTop) {
        yo = 0;
    } else if(align & Qt::AlignBottom) {
        qreal rh = td.documentLayout()->documentSize().height();
        yo = 0;
        yo = qMax((rect.height()-rh), qreal(0));
    } else if(align & Qt::AlignVCenter) {
        qreal rh = td.documentLayout()->documentSize().height();
        yo = 0;
        yo = qMax((rect.height()-rh)/2, qreal(0));
    }
    return QRectF(xo + rect.x(), yo + rect.y(), rect.width(), rect.height());
}

QWidget *myDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const
{
    QTextEdit *textEdit = new QTextEdit(parent);
    return textEdit;
}

void myDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const
{
    QString str = index.data(Qt::DisplayRole).toString();
    QTextEdit *textEdit = qobject_cast<QTextEdit*>(editor);
    textEdit->setHtml(str);
}

void myDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex& index) const
{
    QTextEdit *textEdit = qobject_cast<QTextEdit*>(editor);
    QString str = textEdit->toHtml();
    model->setData(index, str, Qt::DisplayRole);
}

Автор: DarkKnight 13.8.2013, 09:58
Чтобы выделялись строки можно сделать так:
Код

    QListWidget* searchListWidget = new QListWidget();

    QLabel* iw = new QLabel("<b>test0</b>test\nstring2<br>324", searchListWidget );
    iw->setWordWrap(true);
    iw->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    iw->setMaximumHeight(999999);

    int width = iw->width();
    int height = iw->heightForWidth(width);

    QListWidgetItem* lwi = new QListWidgetItem(searchListWidget);
    lwi->setSizeHint(QSize(width, height));

    searchListWidget->setItemWidget(lwi, iw);

Работает и в Win7 и в http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B1%D0%B8%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%B0_%D0%92%D0%BE%D0%BE%D1%80%D1%83%D0%B6%D1%91%D0%BD%D0%BD%D1%8B%D1%85_%D0%A1%D0%B8%D0%BB. 
Qt 4.6.4.

П.С. Судя по дате поста, тебе это уже врят ли нужно, но мб пригодится кому то еще. 

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