Форум сайта python.su
Пробую использовать новый стиль подключения сигналов и слотов.
Есть диалоговое окно с QDialogButtonBox, на котором две кнопки OK и Close. В процессе работы надо сделать так, чтобы нажатие на Close не закрывало диалог, а вызывало другой слот. Раньше делал так
self.btnClose = self.buttonBox.button( QDialogButtonBox.Close ) # отсоединение QObject.disconnect( self.buttonBox, SIGNAL( "rejected()" ), self.reject ) # и подключение к другому слоту QObject.connect( self.btnClose, SIGNAL( "clicked()" ), self.stopProcessing ) .... # восстанавливаем исходное состояние QObject.disconnect( self.btnClose, SIGNAL( "clicked()" ), self.stopProcessing ) QObject.connect( self.buttonBox, SIGNAL( "rejected()" ), self.reject )
self.btnClose = self.buttonBox.button( QDialogButtonBox.Close ) self.buttonBox.rejected.disconnect( self.reject ) self.btnClose.clicked.connect( self.stopProcessing ) ... self.btnClose.clicked.disconnect( self.stopProcessing ) self.buttonBox.rejected.connect( self.reject )
line 147, in prepareProcessЗаменяю эти строки подключения на старый стиль — все работает. В чем может быть дело или это у меня карма плохая?
self.buttonBox.rejected.disconnect( self.reject )
TypeError: disconnect() failed between ‘rejected’ and ‘reject’
Офлайн
Есть диалоговое окно с QDialogButtonBox…Окно создано в Designer, а код сгенерирован через pyqt-uic? Если так, то он генерирует код в котором соединение ‘rejected’ к ‘reject’ выполняется старым способом.
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
Офлайн
Странно.
Попробовал на PySide, там работает нормально. Только если второй раз пытаешься disconnect сделать, тогда вылетает исключение.
На PyQt работает способ с отсоединением всех слотов т.е.
self.ui.buttonBox.rejected.disconnect()
Офлайн
irolnДа, именно так: интерфейс создается в Designer а потом при помощи pyuic4 получаем код
Окно создано в Designer, а код сгенерирован через pyqt-uic?
irolnПохоже, проблема как раз в этом. Отредактировал сгенерированный pyuic4 код, заменив старый стиль на новый и все заработало. Но это костыльное решение, править автоматически генерируемые файлы не самый лучший вариант. Получается новый стиль еще не польностью готов к использованию.
Если так, то он генерирует код в котором соединение ‘rejected’ к ‘reject’ выполняется старым способом.
Офлайн
voltronДа, воспроизводится.
reclosedev, я правильно понимаю, что у тебя на PyQt это воспроизводится?
voltron
Можешь запостить используемые версии Qt, PyQt и Python? Попробую написать в рассылку.
Отредактировано reclosedev (Май 14, 2012 19:21:01)
Офлайн
voltronМда… это провал. Если нет совместимости между api соединения сигналов, когда широко используется и то и то, подобные “прелести” будут лезть как из рога изобилия особенно в тех местах, где что-то генерирует код. Данный пример очень показательный, надо обязательно зарепортить баг в PyQt4.
Похоже, проблема как раз в этом. Отредактировал сгенерированный pyuic4 код, заменив старый стиль на новый и все заработало. Но это костыльное решение, править автоматически генерируемые файлы не самый лучший вариант. Получается новый стиль еще не польностью готов к использованию.
Офлайн
Отписал в рассылку, посмотрим что скажут.
Офлайн
Получил ответ. Вот объяснение почему так происходит:
PyQt allows connections to be made to any Python callable.В качестве workaround'а предлагается реализовать слот-заглушку reject() вида
With old style connections a proxy slot is created under the covers whenever a callable is used (as opposed to when SLOT() is used to refer to a C++ slot). Therefore, in your example, a proxy is always created for the connection to Dialog.reject even though that refers to the object that wraps the C++ slot (as there is no Python reimplementation of reject()).
New style connections are a bit smarter in that they treat slot objects that refer to a wrapped C++ slot and objects that refer to some real Python code differently - a proxy is only created in the latter case.
def reject(self): QDialog.reject(self)
Офлайн
Ясно. Хорошо, что хотя бы доку поправят. Отзывчивые разработчики. :)
Офлайн