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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt CSS и динамические иконки  (Прочитано 8048 раз)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« : Март 05, 2010, 10:28 »

Из-за того, что тролли до сих пор не реализовали фолдинг в QGroupBox-е, решил сделать некую обвязку, чтобы оный заработал.
Для этого планировалось использовать setCheckable(), setFlat() и заменить иконки checkbox-a на (-)/(+).
Т.к. расширить QGroupBox через новый класс не представляется возможным (блин, эти умники зачем-то отказались от QCheckBox-a для реализации checkbox-a и всё перенесли в стили, через которые до стилей самого checkbox-a из QGroupBox-a не добраться), единственным способом изменить иконки checkbox-a можно только через CSS Грустный Ладно, но меня абсолютно не устраивает то, что image задается либо через файл либо через ресурс, т.к. хотелось использовать стилизованные иконки определенные для QStyle::PE_IndicatorBranch.

Поэтому вопрос - возможно ли указать CSS-у использовать динамические images?

Пока делаю так:
Код:
static void createIndicatorSSIcon( QWidget* w, const QString& name, bool checked )
{
QFileInfo info;
QString key = QString( "qt_pixmap_:%1_%2_0_0" ).arg( name ). // формат ключа подглядел в QPixmap::load()
arg( QString::number( info.lastModified().toTime_t() ) );

static const int s = 9; // ### hardcoded in qcommonstyle.cpp

QStyleOption o;
o.rect = QRect( 0, 0, s, s );
o.palette = w->palette();
o.state = QStyle::State_Children;

if( !checked )
o.state |= QStyle::State_Open;

QPixmap* pm = new QPixmap( s, s );
QPainter p( pm );

w->style()->drawPrimitive( QStyle::PE_IndicatorBranch, &o, &p, w );

QPixmapCache::insert( key, *pm );
}

{
. . .

createIndicatorSSIcon( dialog, "groupbox_checked", false );
createIndicatorSSIcon( dialog, "groupbox_unchecked", true );

QGroupBox* gb;

gb->setStyleSheet(
"QGroupBox::indicator:checked{ image: url(:groupbox_checked); }"
"QGroupBox::indicator:unchecked{ image: url(:groupbox_unchecked); }"  );

. . .
}


Такой номер прокатил, но это всё-таки hack, а хочется по-красивее.

И ещё, может подскажете нормальное руководство по Qt CSS?
Записан

Qt 5.11/4.8.7 (X11/Win)
Amigo_sa
Гость
« Ответ #1 : Март 05, 2010, 10:44 »

И ещё, может подскажете нормальное руководство по Qt CSS?
http://doc.crossplatform.ru/qt/4.4.3/stylesheet.html
общие настройки CSS - http://www.htmlbook.ru/css/
Записан
SABROG
Гость
« Ответ #2 : Март 07, 2010, 19:36 »

Можно динамически сохранить нужную картинку в ресурсы с помощью функции

bool QResource::registerResource ( const uchar * rccData, const QString & mapRoot = QString() )   [static]

и прописывать в CSS путь к зарегистрированному ресурсу. Хотя не скажу, что это эффективнее того, что написали вы.

Нельзя. Если бы вы пробовали это сделать, то не отправляли человека заведомо по ложному пути. Разберитесь с этой функцией сначала сами.

GreatSnake, твою проблему можно попробовать решить через QProxyStyle, переопредели в нем метод QStyle::drawPrimitive() и на QStyle::PE_IndicatorBranch рисуй свои картинки. Потом установи твой класс как стиль для QGroupBox контрола. Всего-лишь надо переписать этот код на свой, думаю это не сложно:

Код
C++ (Qt)
   case PE_IndicatorBranch: {
       int mid_h = opt->rect.x() + opt->rect.width() / 2;
       int mid_v = opt->rect.y() + opt->rect.height() / 2;
       int bef_h = mid_h;
       int bef_v = mid_v;
       int aft_h = mid_h;
       int aft_v = mid_v;
#ifndef QT_NO_IMAGEFORMAT_XPM
       static const int decoration_size = 9;
       static QPixmap open(tree_branch_open_xpm);
       static QPixmap closed(tree_branch_closed_xpm);
       if (opt->state & State_Children) {
           int delta = decoration_size / 2;
           bef_h -= delta;
           bef_v -= delta;
           aft_h += delta;
           aft_v += delta;
           p->drawPixmap(bef_h, bef_v, opt->state & State_Open ? open : closed);
       }
#endif // QT_NO_IMAGEFORMAT_XPM
       if (opt->state & State_Item) {
           if (opt->direction == Qt::RightToLeft)
               p->drawLine(opt->rect.left(), mid_v, bef_h, mid_v);
           else
               p->drawLine(aft_h, mid_v, opt->rect.right(), mid_v);
       }
       if (opt->state & State_Sibling)
           p->drawLine(mid_h, aft_v, mid_h, opt->rect.bottom());
       if (opt->state & (State_Open | State_Children | State_Item | State_Sibling))
           p->drawLine(mid_h, opt->rect.y(), mid_h, bef_v);
       break; }
 
« Последнее редактирование: Март 07, 2010, 19:54 от SABROG » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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