Russian Qt Forum
Ноябрь 23, 2024, 17:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: SizeHint или размер столбца.[Решено]  (Прочитано 10698 раз)
Bepec
Гость
« : Апрель 19, 2012, 10:42 »

Приветствую всех Подмигивающий


Проблема: После переопределения делегата(наследован от QItemDelegate), выявились 2 проблемы:

1) При вызове tableView->resizeToColumns(), возвращается двойной размер отрисованной области. Причём в paintEvent с самого начала отрисовки приходит двойной размер :/
Переопределение sizeHint'a не помогает.(Кстати
Код:
вопрос
, за что тогда отвечает sizeHint? - он отвечает за общий размер item'а. Далее пример из QItemDelegate)

Решение: Не переопределённый sizeHint использует размер строки, возвращаемой из модели с ролью Qt::DisplayRole.
Для корректного расчёта размеров, нужно в sizeHint возвращать свой размер(вычисляемый)
В качестве примера выдержка из QItemDelegate

Код:
QSize QItemDelegate::sizeHint(const QStyleOptionViewItem &option,
                              const QModelIndex &index) const
{
    QVariant value = index.data(Qt::SizeHintRole);
    if (value.isValid())
        return qvariant_cast<QSize>(value);
    QRect decorationRect = rect(option, index, Qt::DecorationRole);
    QRect displayRect = rect(option, index, Qt::DisplayRole);
    QRect checkRect = rect(option, index, Qt::CheckStateRole);

    doLayout(option, &checkRect, &decorationRect, &displayRect, true);

    return (decorationRect|displayRect|checkRect).size();
}

2) Текст рисуется не по центру ячейки, а прямо-таки почти впритык к верхней границе.

Решение: в нижеприведённом коде, boundingRect возвращает строку, у которой высота равна высоте шрифта.
Как лечить - увеличивать Rect до высоты ячейки
Код:
        tmpRect.setHeight(outRect.height());

Код:
void LogDelegate::paint(QPainter *painter,
           const QStyleOptionViewItem &option,
           const QModelIndex &index) const
{
    
    painter->setClipRegion(option.rect);
    QString dataStr(index.model()->data(index).toString());
    QString tmpStr;
    int pos;
    QFont font;
    QRect tmpRect;
    QRect outRect(option.rect.topLeft(), option.rect.bottomLeft());
    for(;ttt.contains("##");)
    {
        pos = dataStr.indexOf("##");
        dataStr.remove(0, pos+2);
        tmpStr = dataStr.mid(1, (ttt.indexOf("##")-1));
        
        if (dataStr.at(0) == 'I')
        {
            if (type == 1)
                continue;
            painter->setPen(Qt::red);
        }

        if (dataStr.at(0) == 'R')
        {
            if (type == 0)
                continue;    
            if (type != 1)
                font.setStrikeOut(true);
            painter->setPen(Qt::blue);
        }
        painter->setFont(font);
        tmpRect = painter->boundingRect(outRect, Qt::AlignVCenter, tmpStr);
        painter->drawText(tmpRect, Qt::AlignVCenter, tmpStr);
        outRect = tmpRect;
        painter->drawLine(tmpRect.topLeft(),tmpRect.bottomRight());
      
        //промежуток между частями - чистый
        font.setStrikeOut(false);
        painter->setPen(Qt::black);


        tmpRect = painter->boundingRect(option.rect, option.displayAlignment, "  ");
        tmpRect.moveTo(outRect.topRight());
        outRect = tmpRect;
        painter->drawLine(tmpRect.topLeft(),tmpRect.bottomRight());

    }
}
« Последнее редактирование: Апрель 19, 2012, 13:16 от Bepec » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апрель 19, 2012, 11:55 »

1) При вызове tableView->resizeToColumns(), возвращается двойной размер отрисованной области. Причём в paintEvent с самого начала отрисовки приходит двойной размер :/
Что такое "двойной размер" и почему он возвращается после неизвестной нам resizeToColumns()?

Цитировать
Кстати вопрос, за что тогда отвечает sizeHint?)

Цитата: assistant
Returns the size needed by the delegate to display the item specified by index, taking into account the style information provided by option.

When reimplementing this function, note that in case of text items, QItemDelegate adds a margin (i.e. 2 * QStyle::PM_FocusFrameHMargin) to the length of the text.

Кстати, если хочешь, чтобы работали стили, забудь про QItemDelegate и используй QStyledItemDelegate.
« Последнее редактирование: Апрель 19, 2012, 12:10 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #2 : Апрель 19, 2012, 12:11 »

Угу. Спасибо. Я эту информацию уже читал. Вот только она как бы не соответствует действительности, или я что-то не так делаю.

Двойной размер это - размер отрисованной области, умноженный на 2.

начало области - _B
конец области - _E
начало ячейки - BC
конец ячейки - EC

Получается что-то типа :
       /*                                  */ = область размером с отрисованный текст.

BC_B/*тут отрисовываем текст */_E/*                                  *//*                                  */EC


resizeToColumns() это функция QTableView, которая изменяет размер столбцов в соответствии с sizeHint делегата. НО при возврате в sizeHint делегата значений {(0,0), (100,100), (1000,1000)} ничего не меняется. Увы.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Апрель 19, 2012, 12:17 »

resizeToColumns() это функция QTableView, которая изменяет размер столбцов в соответствии с sizeHint делегата. НО при возврате в sizeHint делегата значений {(0,0), (100,100), (1000,1000)} ничего не меняется. Увы.
Что-то я не вижу такой функции. Есть resizeColumnsToContents().
Показывай твой sizeHint().
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #4 : Апрель 19, 2012, 12:25 »

случай 1: - он у меня не переопределён. эффект присутствует.
случай 2:
Код:
QSize LogDelegate::sizeHint(const QStyleOptionViewItem &option,
               const QModelIndex &index ) const
{
    return QSize(option.rect.width(), option.rect.height());
}

случай 3,4,5: меняется только возвращаемый размер на 0,0; 100,100; 1000,1000;
Код:
QSize LogDelegate::sizeHint(const QStyleOptionViewItem &option,
               const QModelIndex &index ) const
{
    return QSize(1000,1000);
}


И проблема в чём так-то как указать делегату этот самый блин размер ячейки?
update: не "общий размер ячейки на текущий момент", а "размер ячейки, необходимый для корректного отображения содержимого на экране".
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Апрель 19, 2012, 12:38 »

Ещё раз про sizeHint():
Цитировать
Returns the size needed by the delegate to display the item specified by index, taking into account the style information provided by option.

Похоже у тебя с английским что-то совсем никак ибо перевод всё объясняет:
Цитировать
Возвращает размер необходимый делегату для отображения элемента указанного индекса с учетом стиля.
Т.е. твой sizeHint() должен вернуть размер текста, который ты пытаешься отрисовать в paint() но без учёта границ option.rect.
Т.е. если требуется отобразить строку "Abc", то должно возвращаться QFontMetrics( option.font ).boundingRect( "Abc" ).size();
« Последнее редактирование: Апрель 19, 2012, 12:43 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #6 : Апрель 19, 2012, 12:44 »

Кхм. Как бы я это читал, а что он объясняет?

По идее этот размер должен использоваться для определения, весь текст отображён на экране, или нет. А так же для определения ширины колонки.

Цитировать
void QTableView::resizeColumnsToContents () [slot]
Resizes all columns based on the size hints of the delegate used to render each item in the columns.

Так же интересно, что если он не переопределён(sizeHint), а даже если и переопределён, то разницы совершенно никакой.

update на твой update:
Я как бы верю, что размер в QSize(1000, 1000), должен как бы быть достаточным, для отображения 20 символов. И уж точно он должен как- то реагировать хоть на малый размер, хоть на большой.
Но разницы то нет Оо...
« Последнее редактирование: Апрель 19, 2012, 12:46 от Bepec » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Апрель 19, 2012, 12:51 »

Так же интересно, что если он не переопределён(sizeHint), а даже если и переопределён, то разницы совершенно никакой.
Похоже всё дело в том, что строку, которую ты установил для Qt::DisplayRole ты не отображаешь, а используешь как установленную для Qt::UserRole. А дефолтный sizeHint() пытается определить размер для "левой" строки.

Кстати, а ты уверен, что твой sizeHint() вызывается?
« Последнее редактирование: Апрель 19, 2012, 12:54 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #8 : Апрель 19, 2012, 12:57 »

Я её вообще не отображаю Подмигивающий Там лежат сырые данные, которые обрабатываются в делегате и приводятся в юзерочитабельский вид и отрисовываются.

Хм. Проблема исчезла, после нескольких правок(а перед ними были десятки безуспешных) и пересборки проекта... В недоумении.

PS самое удивительное, что уверен. Дебагер там ловит спокойно заход.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Апрель 19, 2012, 12:58 »

Я её вообще не отображаю Подмигивающий Там лежат сырые данные, которые обрабатываются в делегате и приводятся в юзерочитабельский вид и отрисовываются.
Ты-то не отображаешь, а вот дефолтный sizeHint() использует её для подсчёта размера.
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #10 : Апрель 19, 2012, 13:08 »

Оппаньки. Благодарю за эту замечательную, гениальнейшую мысль. Озарило меня теперь Подмигивающий

Тема логически пришла к завершению.  Благодарю за помощь.

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.126 секунд. Запросов: 23.