Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: west от Март 16, 2010, 11:34



Название: QListViewItem
Отправлено: west от Март 16, 2010, 11:34
Подскажите плз, на каком объекте лучше построить свой объект, (аналог QListViewItem), чтобы в каждой колонке у него была кнопка.


Название: Re: QListViewItem
Отправлено: alexman от Март 16, 2010, 11:43
void QTableWidget::setCellWidget ( int row, int column, QWidget * widget )


Название: Re: QListViewItem
Отправлено: west от Март 16, 2010, 11:53
А на ListView не получится? Лениво в таблице заниматься "раскрыванием вложений"


PS: Забыл, кстати, Qt3!


Название: Re: QListViewItem
Отправлено: alexman от Март 16, 2010, 12:09
PS: Забыл, кстати, Qt3!
void Q3Table::setCellWidget ( int row, int col, QWidget * e )


Название: Re: QListViewItem
Отправлено: alexman от Март 16, 2010, 12:15
А нельзя вынести кнопку в отдельное место, а при нажатии на неё анализировать, что за строчка выделена?


Название: Re: QListViewItem
Отправлено: west от Март 16, 2010, 12:17
Да не, с таблицей все понятно. Неочень нравится идея делать в таблице раскрывающиеся вложения. Попробуйте реализовать в таблице отображение файловой структуры, -? А кнопки мне нужны для изменения атрибутов каталогов и файлов.
Может с имитировать наличие управляющего элемента  в ListViewItem пиксмапом?


Название: Re: QListViewItem
Отправлено: west от Март 16, 2010, 12:19
Цитировать
А нельзя вынести кнопку в отдельное место, а при нажатии на неё анализировать, что за строчка выделена?
Интерфейс утвержден заказчиком... ;)


Название: Re: QListViewItem
Отправлено: alexman от Март 16, 2010, 12:55
Можно попробовать унаследоваться от Q3ListViewItem по аналогии Q3CheckListItem...
Посмотри Q3CheckListItem...


Название: Re: QListViewItem
Отправлено: GreatSnake от Март 16, 2010, 14:55
Наследуйся от QListViewItem и уже в его paintCell() рисуй кнопки используя QStyle::drawPrimitive().
Можно посмотреть исходники PropertiesEditor-a designer-a tools/designer/designer/propertyeditor.cpp


Название: Re: QListViewItem
Отправлено: west от Март 16, 2010, 15:05
Цитировать
Наследуйся от QListViewItem и уже в его paintCell() рисуй кнопки используя QStyle::drawPrimitive().
- Похоже, то что надо!
Спасибо.


Название: Re: QListViewItem
Отправлено: west от Март 17, 2010, 09:30
В итоге прикрутил к колонкам QListViewItem QPushButton через размещение кнопок на QListView и отслеживание их геометрии в paintCell каждого item. Код ниже, может кому понадобиться. ;)
header:
Код:
#ifndef BUTTONVIEWITEM_H
#define BUTTONVIEWITEM_H

#include <qlistview.h>
#include <qlist.h>

class QPushButton;

/**
    @author vladimir
*/
class ButtonViewItem : public QListViewItem
{
public:
    ButtonViewItem(QListViewItem *parent = 0, const char *name = 0);
    ButtonViewItem(QListView *parent = 0, const char *name = 0);
    ~ButtonViewItem();

    void setButtonText(const int& col, const QString& text);
    void insertButton(const unsigned int& col, const QString& text = "");
    void setButtonPixmap(const int& col, const QPixmap& pixmap);

private:
    QList<QPushButton> *pbListButton;
    void paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align );
    void hideButtos();
    void setOpen(bool flag);
};

#endif

cpp:
Код:
#include "butviewitem.h"
#include <qpushbutton.h>
#include <qheader.h>

ButtonViewItem::ButtonViewItem(QListViewItem *parent, const char *name)
        : QListViewItem(parent, name)
{
    pbListButton = new QList<QPushButton>();
    pbListButton->setAutoDelete(true);
    for (int i = 0; i < listView()->columns(); i++)
        pbListButton->append(NULL);
}

ButtonViewItem::ButtonViewItem(QListView *parent, const char *name)
        : QListViewItem(parent, name)
{
    pbListButton = new QList<QPushButton>();
    pbListButton->setAutoDelete(true);
    for (int i = 0; i < parent->columns(); i++)
        pbListButton->append(NULL);
}

ButtonViewItem::~ButtonViewItem()
{
    if (pbListButton)
        delete pbListButton;
}

void ButtonViewItem::paintCell ( QPainter * , const QColorGroup & , int column, int width, int )
{
    int w_st = listView()->header()->sectionPos(column) + 2;
    QRect rect = listView()->itemRect(this);
    int delta = listView()->header()->height();
    int h_st = rect.y() + delta + 2;
    if (pbListButton->at(column))
    {
        pbListButton->at(column)->setGeometry(w_st, h_st, width - 1, height() - 1);
        pbListButton->at(column)->show();
    }
}

void ButtonViewItem::setButtonText(const int& col, const QString& text)
{
    if (pbListButton->at(col))
        pbListButton->at(col)->setText(text);
}

void ButtonViewItem::insertButton(const unsigned int& col, const QString& text)
{
    if (!pbListButton->at(col) || pbListButton->count() >= col)
    {
        pbListButton->replace(col, new QPushButton(listView(), "button_item"));
        pbListButton->at(col)->hide();
        setButtonText(col, text);
    }
}

void ButtonViewItem::setButtonPixmap(const int& col, const QPixmap& pixmap)
{
    if (pbListButton->at(col))
        pbListButton->at(col)->setPixmap(pixmap);
}

void ButtonViewItem::setOpen(bool flag)
{
    if (!flag)
    {
        QListViewItemIterator iter( firstChild());
        while (iter.current())
        {
            ((ButtonViewItem*)iter.current())->hideButtos();
            iter++;
        }
    }
    QListViewItem::setOpen(flag);
}

void ButtonViewItem::hideButtos()
{
    for (uint i = 0; i < pbListButton->count(); i++)
        if (pbListButton->at(i))
            pbListButton->at(i)->hide();
}


Название: Re: QListViewItem
Отправлено: GreatSnake от Март 17, 2010, 09:48
Можно, конечно, и так.
Только обычно делают немного по-другому - используют только одну кнопку и двигают на текущую ячейку, а для остальных ячеек кнопку отрисовывают сами.
К тому же это неэффективно в случае большой таблицы.
Интересно, а как вы решили вопрос с фокусом для текущей ячейки/кнопки и отображением текущей строки.
И как работает прокрутка через Up/Down.

К тому же вы забыли определить
virtual int width ( const QFontMetrics & fm, const QListView * lv, int c );
// QListViewItem::paintCell() - if you reimplement this function, you should also reimplement width().
Ведь QListView без этого никогда не узнает реальный размер ячейки.



Название: Re: QListViewItem
Отправлено: west от Март 17, 2010, 10:31
Цитировать
Только обычно делают немного по-другому - используют только одну кнопку и двигают на текущую ячейку, а для остальных ячеек кнопку отрисовывают сами.
- Хорошая Мысль. А как на отисованной QStyle`ом кнопкой написать свою надпись? Или свой пиксмап?
Цитировать
Интересно, а как вы решили вопрос с фокусом для текущей ячейки/кнопки и отображением текущей строки
- Сейчас рожаю.

Цитировать
К тому же вы забыли определить
virtual int width ( const QFontMetrics & fm, const QListView * lv, int c );
- Это точно. Не очень понятно, чего там надо написать, может проще в paintCell вызвать метод базового класса?

Скроллинг тупит.


Название: Re: QListViewItem
Отправлено: GreatSnake от Март 17, 2010, 10:49
Цитата: Я же уже писал
Можно посмотреть исходники PropertiesEditor-a designer-a tools/designer/designer/propertyeditor.cpp
Там всё что вам нужно есть.

Цитировать
Не очень понятно, чего там надо написать
Дык всё просто - (толщина рамки + отступ) * 2 + ширина иконки + ширина текста

Цитировать
может проще в paintCell вызвать метод базового класса?
И QListView отрисует текст ячейки - разве это вам надо?


Название: Re: QListViewItem
Отправлено: west от Март 17, 2010, 13:51
Изменил родителя у QPushButton на listView()->viewport() и почти все пошло, кое какие артефакты убрал ручками, а так все вроде гуд.