Найти - Пользователи
Полная версия: PyQt4: не ловится closeEvent в виджетах
Начало » GUI » PyQt4: не ловится closeEvent в виджетах
1 2
truporez
__del__ поможет только частично, так как в момент вызова сам виджет уже удален.
Андрей Светлов
У __del__ свои тараканы. Объект, реализовавший этот метод, не собирается python garbage collector. Т.е. простой decref для него работает, а gc видит - но игнорирует. Иногда это дает довольно неожиданные эффекты. Конечно, все лечится - но внимания требует больше.
pasaranax
А если там вызвать self.__super__.__del__(self), то все равно?
truporez
Задачу решил вызовом своего сигнала на который подписал виджеты, которые должны знать о закрытии диалога.

self.connect(self, QtCore.SIGNAL("mycloseevent()"), self.mywidget.close_event)
и по closeEvent() делаю emit

self.emit(QtCore.SIGNAL("mycloseevent()"))
gmorgunov
Можно чуть проще(есть сигнал destroyed() ) :
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from PyQt4 import QtGui,QtCore
#import logging
import sys

class TestWidget( QtGui.QWidget ):
def __init__( self, parent=None ):
QtGui.QWidget.__init__( self, parent )
self.verticalLayout = QtGui.QVBoxLayout(self)
self.label = QtGui.QLabel("TestLabel", self)
self.verticalLayout.addWidget(self.label)
def close_event(self):
print "TestWidget closeEvent"

class TestDialog( QtGui.QDialog ):
def __init__( self, *args ):
QtGui.QWidget.__init__( self, *args )
gridLayout = QtGui.QGridLayout(self)
self.mywidget = TestWidget(self)
gridLayout.addWidget( self.mywidget, 0, 0, 1, 1)
self.connect(self, QtCore.SIGNAL("destroyed()"), self.mywidget.close_event)
def closeEvent(self, event):
print "TestDialog closeEvent"
event.accept()

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
TestDialog().exec_()
truporez
gmorgunov: при подписывании на destroyed() возникает та же проблема что и при __del__, на момент вызова qt-шный объект уже уничтожен и его атрибуты не доступны.
gmorgunov
Экспериментально выяснил: QEvent.Close (closeEvent(event)) действительно не отправляется ребенку(TestWidget), но после закрытия окна(TestDialog), TestWidget-у отправляется 2 события: QEvent.WindowDeactivate и QEvent.Hide. Любое из них можно обработать.
Вот так работает без сигналов:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class TestWidget(QWidget ):
def __init__( self, parent=None ):
QWidget.__init__( self, parent )
self.verticalLayout = QVBoxLayout(self)
self.label = QLabel("TestLabel", self)
self.verticalLayout.addWidget(self.label)
def event(self,event):
if event.type() == QEvent.Hide:
print "WIDGET", self.label.text()
return QWidget.event(self, event) # Отправляем дальше
class TestDialog(QDialog ):
def __init__( self, *args ):
QWidget.__init__( self, *args )
gridLayout = QGridLayout(self)
self.mywidget = TestWidget(self)
gridLayout.addWidget( self.mywidget, 0, 0, 1, 1)
self.count=0
def closeEvent(self, event):
print "DIALOG"
event.accept()
if __name__ == "__main__":
app = QApplication(sys.argv)
TestDialog().exec_()
truporez
Немного доработал пример, чтоб не ловить все события.
    def hideEvent(self, event):
logging.debug("widget's hideevent (%s)" % event)
event.accept()
Плохо, что hideEvent срабатывает при переключении закладки, если виджет размещен в QTabWidget.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB