Russian Qt Forum

Qt => QSS => Тема начата: Polt от Июнь 17, 2011, 09:48



Название: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 09:48
Два вигета.

Первый имеет фиксированный размер 50x50 и background-color: qlineargradient(..).
Второй имеет фиксированный размер 20x20, располагается поверх первого, сидит в QGridLayout и не имеет стиля.

Необходимо чтобы второй вигет ничего не наследовал от второго и не имел стиля.

a. Если устанавливать setstylesheet у первого вигета через селектор # по имени, то есть для него одного, а у второго вигета не устанавливать setstylesheet все чудесно работает как мне надо.
b. Если устанавливать setstylesheet у первого вигета через QWidget{...} или .QWidget{...}, а у второго не устанавливать setstylesheet, второй вигет наследует стиль верхнего, ошибка.

Если у второго вигета не устанавливать parent ничего не меняется для случая b.

Подобных тем на форуме десятки. Мой вопрос такой.

Как сделать так чтобы второй вигет не наследовал стиль от первого без использования селектора #. Как решить данную задачу без setObjectName  у вигетов, а только через setStyleSheet?


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 10:28
Оба просто типа QWidget?


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 10:31
Да


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 10:36
Например:
Код
CSS
QWidget[width="50"]
{
  …
}


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 10:40
Хех. Какой вопрос такой и ответ. Это не побходит. Черезжопно.

Тогда добавляем в грид третий вигет с width 50, у него должен быть setstylesheet с каким-то фоном y. А второй вигет все еще не должен наследовать стиль от первого.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 11:05
Какой вопрос такой и ответ.
Именно.

А второй вигет все еще не должен наследовать стиль от первого.
На то они и каскадные стили, чтобы наследоваться.  :)
Так что
1) либо через имя (или другое отличающееся property)
2) либо через класс (заводим наследника от QWidget, преобразуем нужный виджет в него, ставим css именно на этот класс)
3) либо через известную иерархию ( например .QMainWindow > .QWidget )


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 11:17
Да это я знаю.

Не хочется забивать objectName вигетов одинаковыми именами. ObjectName-ы могут ведь и понадобиться не только под стили)
Уныло. Мб все-таки есть способ через setStyleSheet передать стиль конкретному объекту без селектора по имени?


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 11:21
Уныло. Мб все-таки есть способ через setStyleSheet передать стиль конкретному объекту без селектора по имени?
Есть, второй пункт. Делаете
Код
C++ (Qt)
class MyStyledWidget : public QWidget
{
   Q_OBJECT
   ...
}
И кастуете нужные виджеты в него.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: GreatSnake от Июнь 17, 2011, 11:30
Первый имеет фиксированный размер 50x50 и background-color: qlineargradient(..).
Второй имеет фиксированный размер 20x20, располагается поверх первого, сидит в QGridLayout и не имеет стиля.
Проясните - первый является родителем второго?


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 11:32
Так это тоже понятно. Но представьте для каждого вигета, который должен содержать новый стиль создавать свой тип. Хотя, почему бы и нет.

Если бы архитектура программы продумывалась заного мб я бы и пошел по такому пути, не было бы проблем. Но программа уже написана, стилей навешано очень много и все работает через #name. Хотелось определить namespace со стилями и возвращать стили в нужные вигеты, ммм что-то вроде:

w->setStyleSheet(QSSBlack::QWIDGET_GRAY);
w1->setStyleSheet(QSSBlack::QWIDGET_WHITEG);


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 11:35
....
QWidget * wtop = new QWidget(this);
wtop->setStyleSheet(...);

QWidget * w = new QWidget(this);

QGridLayout * gBox = new QGridLayout(wtop);
....
gBox->addWidget(w, 0, 0)
....


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: GreatSnake от Июнь 17, 2011, 11:50
Хм, что я делаю не так ???
Код
C++ (Qt)
#include <QApplication>
#include <QGridLayout>
#include <QPushButton>
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
QWidget w;
 
w.setStyleSheet( ".QWidget { background-color: cyan }" );
 
QGridLayout gl( &w );
 
for( int i = 0; i < 3; i++ )
for( int j = 0; j < 3; j++ )
{
QPushButton* pb = new QPushButton(
QString( "%1:%2" ).arg( i ).arg( j ) );
gl.addWidget( pb, i, j );
}
 
w.show();
return app.exec();
}
 


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 11:53
Вы используете разные классы. Поменяйте qpushbutton на qwidget.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 13:37
Так это тоже понятно. Но представьте для каждого вигета, который должен содержать новый стиль создавать свой тип. Хотя, почему бы и нет.

Если бы архитектура программы продумывалась заного мб я бы и пошел по такому пути, не было бы проблем. Но программа уже написана, стилей навешано очень много и все работает через #name. Хотелось определить namespace со стилями и возвращать стили в нужные вигеты, ммм что-то вроде:

w->setStyleSheet(QSSBlack::QWIDGET_GRAY);
w1->setStyleSheet(QSSBlack::QWIDGET_WHITEG);
Ну раз #name всё же есть, то можно так:

Код
C++ (Qt)
QString QWIDGET_GRAY = "собственно css без селекторов";
SetCSS( w, QSSBlack::QWIDGET_GRAY );
где SetCSS:
Код
C++ (Qt)
void SetCSS( QWidget* widget, QString css )
{
   widget->setStyleSheet( "#" + widget->objectName() + " {" + css + "}";
}

Или можно даже, на случай если имени у виджета ещё нет имени, генерировать ему уникальное имя:
Код
C++ (Qt)
void SetCSS( QWidget* widget, QString css )
{
   if ( widget->objectName().isEmpty() )
   {
       widget->setObjectName( QString::number( (size_t)widget, 16 ) );
   }
   widget->setStyleSheet( "#" + widget->objectName() + " {" + css + "}";
}


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 13:55
LisandreL, вы все хотите навязать #objectName. У меня итак уже все написано через #objectName.

Вопрос остается.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 14:10
Ну а как вы ещё хотите определить именно этот виджет? Ну используйте accessibleName вместо этого.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 14:14
Ну мб есть еще какой-то хитрый синтаксис qss, который можно передать непосредственно через setstylesheet(qss_string) объекту, чтобы наложить стиль именно на него. Но похоже что нет.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 14:16
Это каскадные стили. Каскадные значит на всю иерархию объектов.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: Polt от Июнь 17, 2011, 14:27
Ну ничего не помешало что каскадных стилей организовать #objectName.


Название: Re: вопрос по QSS, как обойти ID Selector
Отправлено: LisandreL от Июнь 17, 2011, 14:54
Ну мб есть еще какой-то хитрый синтаксис qss, который можно передать непосредственно через setstylesheet(qss_string) объекту, чтобы наложить стиль именно на него
Чем мой вариант не устраивает с SetCSS()? Если так уж не нравится objectName, заведите своё новое проперти и цепляйтесь через него.