Russian Qt Forum

Qt => QSS => Тема начата: Andrew12 от Февраль 16, 2011, 14:15



Название: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: Andrew12 от Февраль 16, 2011, 14:15
Здравсвтвуй, многоуважаемый All!

Тупик полный!
Был создан класс APush, наследник QPushButton.
Было создано Q_PROPERTY(QVariant shadowLength READ getShadowLength WRITE setShadowLength )
Были присвоены CSS, через app.setStyleSheet(styleSheet);

styleSheet такое:
Код:
APush {
qproperty-shadowLength : 1;
border:0px;}
APush:pressed  {
qproperty-shadowLength : 3;
border:3px solid black;}

Проблемма в том, что при нажатии на APush, его border изменяется на 3 сам, а shadowLength необходимо обрабатывать вручную. Если отслеживать this->property("shadowLength"), то оно устанавливается в состояние 1 при создании элемента само и более не изменяется при нажатии на APush (функция setShadowLength срабатывает 1 раз).

Вопрос: как отследить созданное свойство shadowLength объекта APush в состоянии pressed?


Название: Re: Проблемма с состоянием :pressed в custom widget с изпользованием StyleSheet
Отправлено: Igore от Февраль 16, 2011, 14:37
В конструкторе APush добавь вызов ensurePolished()


Название: Re: Проблемма с состоянием :pressed в custom widget с изпользованием StyleSheet
Отправлено: Andrew12 от Февраль 16, 2011, 14:54
Добавил. Ничего не поменялось. С каждым APush::paintEvent вывожу в консоль this->property("shadowLength") и оно неизменно (равно - 1).

Насколько я понимаю css устанавливается один раз и посему свойство shadowLength должно где-то храниться для обычного состояния и для состояния :pressed. Вот как получить доступ к этому свойству?!


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: Igore от Февраль 16, 2011, 15:29
Проверяй лучше, у меня работает.

Код:
class MyButton : public QPushButton
{
    Q_OBJECT

private:
    int m_test;

public:
    MyButton(QWidget* Parent = 0) : QPushButton(Parent), m_test(0) {this->ensurePolished();}
    virtual ~MyButton();

    Q_PROPERTY(int test READ getTest WRITE setTest);

    void setTest(int test){m_test = test};
    int getTest() const {return m_test;};
};

    MyButton* my = new MyButton(this);
    qDebug() << my->getTest();//0
    my->setStyleSheet("qproperty-test:5");
    qDebug() << my->getTest();//5

Упс, наврал, проверил с pressed не устанавливает.


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: Andrew12 от Февраль 16, 2011, 15:43
Так и у меня работает.
Но когда нажимаешь на кнопку, this.property("qproperty-shadowLength") должен ставать равный 3 (в соответствии со стилем APush:pressed), а он, зараза, как установился =1 в самом начале, так и остается.

Я постоянно отрисовываю кнопку и вывожу это свойство :
void APush::paintEvent(QPaintEvent *event) {
...
qDebug() << this.property("qproperty-shadowLength").toString(); // 1
}

Может кто со специалистов подключится? Пишу кнопку с rich текстом, прозрачным фоном и отбрасыванием теней от картинки!


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: yoyo от Февраль 16, 2011, 16:04
Не уверен, но возможно в Q_PROPERTY нехватает уведомления на изменение этого свойства.

Код:
Q_PROPERTY(int test READ getTest WRITE setTest NOTIFY changeTest)
...
signals:
    void changeTest();
...
void APush::setTest(int newValue)
{
    if (m_Test != newValue)
    {
        m_Test = newValue;
        emit changeTest();
    }
}




Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: Andrew12 от Февраль 16, 2011, 17:02
Не выходит. Давай подумаем так:

Имеем.
Код:
APush:pressed  {qproperty-shadowLength : 3;

Есть два варинта развития событий, при нажатии APush. Хотелось бы понять:
Вариант 1: происходит ли динамическое изменение свойства?
Вариант 2: или свойства заносятся, при создании элемента и, если состояние=pressed, необходимо их где-то взять?



Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: meego_man от Февраль 16, 2011, 18:42
Не выходит. Давай подумаем так:

Имеем.
Код:
APush:pressed  {qproperty-shadowLength : 3;

Есть два варинта развития событий, при нажатии APush. Хотелось бы понять:
Вариант 1: происходит ли динамическое изменение свойства?
Вариант 2: или свойства заносятся, при создании элемента и, если состояние=pressed, необходимо их где-то взять?

Похоже что таблицы стилей не позволяют динамически изменять дополнительные свойства. А почему не использовать стандартный способ signal-slot?


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: Andrew12 от Февраль 16, 2011, 19:00
Да в том-то и дело, что это возможно.
У меня лежит элемент без исходного кода, который при помощи CSS меняет свойства объекта через qproperty-, в том числе и в нажатом состоянии.

Вопрос, только как : через Q_Property(WRITE), либо другим способом.

Почему, через CSS? Да потому, что очень удобно делать анимированные кнопки. В нажатом состоянии мы просто убираем тень, что визуально напоминает нажатие кнопки.


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: meego_man от Февраль 17, 2011, 13:59
Да в том-то и дело, что это возможно.
У меня лежит элемент без исходного кода, который при помощи CSS меняет свойства объекта через qproperty-, в том числе и в нажатом состоянии.

Вопрос, только как : через Q_Property(WRITE), либо другим способом.

Почему, через CSS? Да потому, что очень удобно делать анимированные кнопки. В нажатом состоянии мы просто убираем тень, что визуально напоминает нажатие кнопки.
Ммм, ну если очень хочется, могу только предложить небольшой хак:
Код:
class testButton : public QPushButton
{
  Q_OBJECT
  Q_PROPERTY (int testProp READ getTestProp WRITE setTestProp)
public:
  explicit testButton (QWidget *parent = 0);
  int getTestProp ()
  {
    return testProp;
  }
  void setTestProp (int pPropVal)
  {
    testProp = pPropVal;
    setText (QString ().setNum (testProp));
  }

protected:
  virtual void mousePressEvent (QMouseEvent * e)
  {
    QPushButton::mousePressEvent (e);
    this->style ()->polish (this);
  }
  virtual void mouseReleaseEvent (QMouseEvent * e)
  {
    QPushButton::mouseReleaseEvent (e);
    this->style ()->polish (this);
  }

private:
  int testProp;
};

testButton::testButton(QWidget *parent) :
    QPushButton(parent)
{
  this->setStyleSheet (QLatin1String ("testButton {qproperty-testProp:1; border:0px;} testButton[down='true'] {qproperty-testProp:3; border:3px solid black;}"));
}
Проблема в том, что если нужна реакция на нажатие клавиш клавиатуры, то придеться также и их переопределять :) Может это наведет на какую нить другую мысль


Название: Re: Проблемма с состоянием стиля :pressed в custom widget - НЕ решено!!
Отправлено: yoyo от Февраль 17, 2011, 16:51
Способ в самом деле работает! Понятно, что для приведения свойств виджета в "актуальное состояние" необходим вызов style()->polish(this). Я бы только предложил вызывать его из paintEvent. Накладные расходы не столь существенны и не нужны другие обработчики событий.
Код:
void MyPushButton::paintEvent(QPaintEvent *e)
{
    style()->polish(this);
    QPushButton::paintEvent(e);
}
Однако, мне совсем не понятно, почему данный метод не срабатывает для псевдо-состояния ":pressed", но прекрасно работает для "[down='true']".