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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Наследование стилей дочерними виджетами  (Прочитано 5774 раз)
Nimbus
Гость
« : Август 17, 2010, 05:16 »

Доброго времени суток. Сразу к делу - есть два стула спойлер, то есть мой виджет, унаследованный от класса QWidget. Этот спойлер содержит в себе заголовок, состоящий из двух QLabel, а также сам контент, скрывающийся под спойлером, то есть ещё один виджет, находящийся под заголовком и скрывающийся/появляющийся по клику на любой из лейблов заголовка. Вобщем, нужно применить стили CSS к заголовку и к самому спойлеру, но не к виджету-контенту.

Код:
labelex.h
Код
C++ (Qt)
#ifndef LABELEX_H
#define LABELEX_H
 
#include "common.h"
 
class LabelEx : public QLabel {
Q_OBJECT
public:
LabelEx(QLabel *pwgt) :
QLabel(pwgt)
{
 
}
protected:
virtual void mousePressEvent(QMouseEvent *pe)
{
if (pe->button() == Qt::LeftButton)
emit clicked();
}
signals:
void clicked();
};
 
#endif
 

header.h
Код
C++ (Qt)
#ifndef HEADER_H
#define HEADER_H
 
#include "labelex.h"
 
class Header : public QWidget {
Q_OBJECT
private:
LabelEx *pBtn;
bool expanded;
void refresh()
{
pBtn->setPixmap(QPixmap(expanded ? ":/img/collapse.png" : ":/img/expand.png"));
}
public:
Header(QWidget *pwgt, const QString& Title) : QWidget(pwgt)
{
pBtn = new LabelEx(0);
expanded = false;
pBtn->setPixmap(QPixmap(":/img/expand.png"));
 
LabelEx *pTitle = new LabelEx(0);
QFont font("Impact");
font.setPointSize(9);
pTitle->setFont(font);
pTitle->setText(Title);
pBtn->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
pTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
setStyleSheet("border-width: 1px; border-color: #565656; border-style: solid; background-color: #E6E6E6; border-radius: 0px;");
QHBoxLayout *hbx = new QHBoxLayout;
hbx->setSpacing(0);
hbx->addWidget(pBtn);
hbx->addWidget(pTitle);
setLayout(hbx);
connect(pBtn, SIGNAL(clicked()), SLOT(click()));
connect(pTitle, SIGNAL(clicked()), SLOT(click()));
 
}
 
~Header()
{
delete layout();
}
 
bool isExpanded()
{
return expanded;
}
 
void expand()
{
expanded = true;
refresh();
}
 
void collapse()
{
expanded = false;
refresh();
}
 
private slots:
void click()
{
expanded = !expanded;
refresh();
emit clicked();
}
signals:
void clicked();
};
 
#endif
 

spoiler.h
Код
C++ (Qt)
#ifndef SPOILER_H
#define SPOILER_H
 
#include "header.h"
 
class Spoiler : public QWidget {
Q_OBJECT
private:
QWidget *pWidget;
Header *pHeader;
bool expanded;
public:
Spoiler(QWidget *pwgt, const QString&, QWidget*);
private slots:
void headerClicked();
public slots:
void expand();
void collapse();
};
#endif
 

spoiler.cpp
Код
C++ (Qt)
#include "spoiler.h"
 
Spoiler::Spoiler(QWidget *pwgt, const QString &Title, QWidget *Widget) : QWidget(pwgt), pWidget(Widget)
{
if (!pWidget)
Error(QString("Не проинициализирован виджет спойлера %1").arg(Title));
pHeader = new Header(0, Title);
QVBoxLayout *vbx = new QVBoxLayout;
vbx->setAlignment(Qt::AlignTop);
vbx->setSizeConstraint(QLayout::SetMinimumSize);
setStyleSheet("Spoiler { border-width: 1px; border-style: solid; border-color: #F47300; border-radius: 5px; background-color: #A0A0A0; }");
setContentsMargins(5, 5, 5, 1);
pWidget->setVisible(false);
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
vbx->setSpacing(0);
vbx->addWidget(pHeader);
vbx->addWidget(pWidget);
setLayout(vbx);
connect(pHeader, SIGNAL(clicked()), SLOT(headerClicked()));
}
 
void Spoiler::headerClicked()
{
pWidget->setVisible(pHeader->isExpanded());
}
 
void Spoiler::collapse()
{
pHeader->collapse();
pWidget->setVisible(false);
}
 
void Spoiler::expand()
{
pHeader->expand();
pWidget->setVisible(true);
}
 

И да, немного, конечно, извращённо, но не карайте строго.
Стиль в конструкторе спойлера вообще не применяется ни к чему.
Если я напишу в конструкторе спойлера
Код
C++ (Qt)
setStyleSheet("border-width: 1px; border-style: solid; border-color: #F47300; border-radius: 5px; background-color: #A0A0A0;");
 
, то применится это только к виджету-контенту. А мне надо, чтобы применилось только к самому спойлеру, но его виджеты были незатронуты, за исключением, если у них уже будут применены свои стили.
Пробовал ещё так
Код
C++ (Qt)
setObjectName("spoiler");
setStyleSheet("QWidget#spoiler { border-width: 1px; border-style: solid; border-color: #F47300; border-radius: 5px; background-color: #A0A0A0; }");
 
, но эффект остался прежним - ничего не применилось.
Ну и напоследок делаю так
Код
C++ (Qt)
setStyleSheet(".QWidget { border-width: 1px; border-style: solid; border-color: #F47300; border-radius: 5px; background-color: #A0A0A0; }");
 
и тоже эффекта ноль.
Как справиться с этой проблемой?
Записан
BRE
Гость
« Ответ #1 : Август 17, 2010, 08:20 »

Сам класс QWidget не поддерживает стили, его метод paintEvent просто ничего не делает, хотя все следующие потомки уже умеют это делать.
Можно (и наверное стоит) наследовать Spoiler от одного из потомков QWidget, например QFrame или реализовать рисование самому:
Код
C++ (Qt)
void Spoiler::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.init( this );
    QPainter p( this );
    style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
}
 
Записан
trot
Гость
« Ответ #2 : Август 17, 2010, 20:52 »

Есть подозрения, что у виджета нельзя задавать бордюры. Попробуй ради эксперимента управлять заливкой виджета, чтобы убедиться в том стили вообще применяются.
Записан
Nimbus
Гость
« Ответ #3 : Август 18, 2010, 09:44 »

Есть подозрения, что у виджета нельзя задавать бордюры. Попробуй ради эксперимента управлять заливкой виджета, чтобы убедиться в том стили вообще применяются.
Да я уже сделал как сказал BRE (спасибо ему). В CSS всё-таки ещё не всё предусмотрели Грустный
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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