2012-02-08 2 views
3

У меня есть несколько QComboBoxes в моем графическом интерфейсе PyQt4/Python3, и они заполняются некоторыми записями из базы данных во время инициализации. Исходное значение CurrentIndex равно 0. Существует также галочка, которая меняет язык элементов в моих списках. Чтобы сохранить текущий пользовательский выбор, я делаю резервный индекс текущего элемента и setCurrentIndex с этим номером после того, как я заполнил ComboBox с переведенными элементами. Все эти действия испускают сигнал currentIndexChanged.Отдельное взаимодействие пользователя с программным изменением: PyQt, QComboBox

На основе элементов, выбранных в QComboBoxes, отображается какой-либо график. Идея состоит в том, чтобы перерисовать сюжет онлайн - как только пользователь изменит текущий элемент ComboBox. И здесь у меня проблема, так как если я перерисовываю график каждый раз, когда выдается сигнал currentIndexChanged, я повторно его повторно и несколько раз во время инициализации, и если выбор галочки перевода был изменен.

Каков наилучший способ отделить эти случаи? В принципе мне нужно отделить от пользователя текущий программный текущий Индексный переход и обновить график только в более позднем случае (во время инициализации GUI я могу запрограммировать функцию графика печати один раз). Должен ли я писать/переписывать любой сигнал? Если это так, я никогда раньше этого не делал и приветствовал бы любой намек или хороший пример. Использовать другой сигнал? Или, может быть, есть способ временно заблокировать все сигналы?

ответ

9

Есть несколько разных вещей, которые вы можете попробовать.

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

Во-вторых, вы можете использовать сигнал activated, который отправляется только тогда, когда пользователь выбирает элемент. (Но учтите, что, в отличие от currentIndexChanged, этот сигнал отправляется, даже если индекс не изменился).

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

Вот скрипт, который демонстрирует следующие возможности:

from PyQt4 import QtGui, QtCore 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     layout = QtGui.QVBoxLayout(self) 
     self.combo = QtGui.QComboBox() 
     self.combo.setEditable(True) 
     self.combo.addItems('One Two Three Four Five'.split()) 
     self.buttonOne = QtGui.QPushButton('Change (Default)', self) 
     self.buttonOne.clicked.connect(self.handleButtonOne) 
     self.buttonTwo = QtGui.QPushButton('Change (Blocked)', self) 
     self.buttonTwo.clicked.connect(self.handleButtonTwo) 
     layout.addWidget(self.combo) 
     layout.addWidget(self.buttonOne) 
     layout.addWidget(self.buttonTwo) 
     self.changeIndex() 
     self.combo.activated['QString'].connect(self.handleActivated) 
     self.combo.currentIndexChanged['QString'].connect(self.handleChanged) 
     self.changeIndex() 

    def handleButtonOne(self): 
     self.changeIndex() 

    def handleButtonTwo(self): 
     self.combo.blockSignals(True) 
     self.changeIndex() 
     self.combo.blockSignals(False) 

    def changeIndex(self): 
     index = self.combo.currentIndex() 
     if index < self.combo.count() - 1: 
      self.combo.setCurrentIndex(index + 1) 
     else: 
      self.combo.setCurrentIndex(0) 

    def handleActivated(self, text): 
     print('handleActivated: %s' % text) 

    def handleChanged(self, text): 
     print('handleChanged: %s' % text) 

if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

Спасибо большое за хорошей иллюстрацией! Я принял решение blockSignals. Кстати, действительно ли возможно «убедиться, что вы выполняете всю свою инициализацию, прежде чем подключать сигналы», если я использую конструктор QT, а не макет программы, как в примере? В какой момент сигналы активируются? – Katya

+0

@ Katya. С Qt Designer вы можете подключать только существующие сигналы до уже существующих слотов (в отличие от ваших собственных обработчиков). Таким образом, на практике почти все сигналы должны подключаться _after_ gui был настроен (если приложение не очень простое). Лично я использую Qt Designer для выкладки gui и очень редко использую его для подключения сигналов. – ekhumoro

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