2014-01-11 1 views
3

В последнее время я борюсь с пониманием использования pyqtProperty. В следующем фрагменте я пытаюсь создать пользовательскую кнопку, которая изменит ее текст и внешний вид после нажатия на нее. Я хотел разделить логику и внешний вид, поэтому я создал пользовательское свойство «состояние», которое используется в таблице стилей.Python + Qt: pyqtProperty, таблицы стилей и обработчики событий

Результат выглядит странным для меня. Программа выбрасывает 'CustomButton' object has no attribute '_state' исключение, но работает в любом случае. Текст кнопки меняется после нажатия на нее, но цвет остается неизменным.

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import sys 
from PyQt4 import QtGui, QtCore 

STYLE = ''' 
CustomButton { 
    margin: 50px; 
    padding: 10px; 
} 
CustomButton[state='true'] { 
    background: yellowgreen; 
} 
CustomButton[state='false'] { 
    background: orangered; 
} 
''' 


class CustomButton(QtGui.QPushButton): 
    def __init__(self): 
     super(CustomButton, self).__init__() 
     self.setText('ON') 
     self.setStyleSheet(STYLE) 
     self._state = True 

    def g_state(self): 
     return self._state 

    def s_state(self, value): 
     self._state = value 

    state = QtCore.pyqtProperty(bool, fget=g_state, fset=s_state) 

    def mousePressEvent(self, event): 
     print 'clicked' 
     if self.state == True: 
      self.state = False 
      self.setText('OFF') 
     else: 
      self.state = True 
      self.setText('ON') 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    b = CustomButton() 
    b.show() 
    sys.exit(app.exec_()) 

ответ

3

Здесь есть пара вопросов.

Во-первых, повторно реализованный mousePressEvent должен вызывать реализацию базового класса, чтобы сохранить нормальное поведение.

Во-вторых, изменения в свойствах не автоматически вызывают изменения стиля, поэтому вам нужно явно сделать это в своем коде.

Также стоит отметить, что pyqtProperty может использоваться в качестве декоратора, что может немного улучшить читаемость кода.

Таким образом, с этими изменениями, код может выглядеть примерно так:

... 

    @QtCore.pyqtProperty(bool) 
    def state(self): 
     return self._state 

    @state.setter 
    def state(self, value): 
     self._state = value 

    def mousePressEvent(self, event): 
     print 'clicked' 
     if self.state: 
      self.state = False 
      self.setText('OFF') 
     else: 
      self.state = True 
      self.setText('ON') 
     self.style().unpolish(self) 
     self.style().polish(self) 
     self.update() 
     super(CustomButton, self).mousePressEvent(event) 
+0

Большое спасибо, ekhumoro! Теперь он работает по назначению. Что меня беспокоит, так это то, что документация ничего не говорит об этой польской/неполивной штуковине. http://qt-project.org/doc/qt-4.8/stylesheet-examples.html#customizing-using-dynamic-properties Кроме того, я до сих пор получаю это странное исключение: 'Traceback (последний последний вызов): Файл «style.py», строка 29, в g_state return self._state AttributeError: объект «CustomButton» не имеет атрибута «_state» –

+0

О, неважно, я нашел еще один документ, который объясняет это: http://qt-project.org/wiki/DynamicPropertiesAndStylesheets Еще раз спасибо, случай закрыт. –

+1

@ АнтонМельников. Извините, я забыл обработать AttributeError. Это связано с тем, что вы настраиваете таблицу стилей перед созданием атрибута '_style'. – ekhumoro

Смежные вопросы