Package: python-qt4 Version: 4.7.3-1+b1 Severity: normal In a Python program I use setItemWidget() to add widgets to columns of QTreeWidgetItems (eg QPushButton, QComboBox, etc).
When a widget is no longer needed it is removed using removeItemWidget(), however this action causes the removal of the QTreeWidgetItem itself instead of just removing the item widget attached by setItemWidget(). Problem goes away if extra references to QTreeWidgetItems are kept somewhere outside the QTreeWidget instance. This problem does not occur in a C++ implementation. Files attached can help demonstrate the issue: bug.py: Python script demonstrating the bug; if run without arguments bug shows up (disappearing QTreeWidgetItems); if run with a single argument 'workaround' the script artificially keeps extra references causing QTreeWidgetItems to stay in their places; program uses a timer to add and remove item widgets after short delays; ctl-Q quits the program. bug.ui: GUI file from designer-qt4 for both python version and C++ version. bug.cpp bug.h: C++ "translation" of bug.py; shows setItemWidget/removeItemWidget working as expected. bug.mk Simple Makefile to compile everything. *** bug.py #! /usr/bin/python from PyQt4 import QtGui as Qg from PyQt4 import QtCore as Qc from PyQt4 import Qt from ui_bug import Ui_MainWindow import sys class MainWindow(Qg.QMainWindow, Ui_MainWindow): def __init__(self, workaround=True): Qg.QMainWindow.__init__(self) Ui_MainWindow.__init__(self) self.setupUi(self) self.connect(self.actionExit, Qc.SIGNAL('triggered()'), self.__exit) self.__timer = Qc.QTimer(self) self.connect(self.__timer, Qc.SIGNAL('timeout()'), self.__sequence) self.__state = 0 self.__timer.setSingleShot(True) self.__timer.start(2000) if workaround: print 'WARNING: using removeItemWidget() bug workaround' tw = self.treeWidget nitems = tw.topLevelItemCount() self.__items = [tw.topLevelItem(k) for k in range(nitems)] else: self.__items=[] def __sequence(self): treew = self.treeWidget nitems = treew.topLevelItemCount() if nitems < 1: print 'ERROR: no items left'; return col = 1 if self.__state==0: print 'adding %d item widgets to column %d' % (nitems,col) for k in range(nitems): item = treew.topLevelItem(k) pbut = Qg.QPushButton(item.text(col),self) treew.setItemWidget(item, col, pbut) item.setText(col, '') self.__state+=1 self.__timer.start(2000) elif self.__state==1: print 'removing %d item widgets from column %d' % (nitems,col) for k in range(nitems): item = treew.topLevelItem(k) pbut = treew.itemWidget(item, col) item.setText(col, pbut.text()) treew.removeItemWidget(item, col) self.__state+=1 self.__timer.start(2000) def __exit(self): Qg.QApplication.closeAllWindows() if __name__ == '__main__': app = Qg.QApplication([]) gui = MainWindow('workaround' in sys.argv[1:]) gui.show() sys.exit(app.exec_()) *** bug.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTreeWidget" name="treeWidget"> <property name="rootIsDecorated"> <bool>false</bool> </property> <column> <property name="text"> <string>1</string> </property> </column> <column> <property name="text"> <string>2</string> </property> </column> <column> <property name="text"> <string>3</string> </property> </column> <item> <property name="text"> <string>a</string> </property> <property name="text"> <string>b</string> </property> <property name="text"> <string>c</string> </property> </item> <item> <property name="text"> <string>x</string> </property> <property name="text"> <string>y</string> </property> <property name="text"> <string>z</string> </property> </item> </widget> </item> </layout> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>26</height> </rect> </property> <widget class="QMenu" name="menuFile"> <property name="title"> <string>File</string> </property> <addaction name="actionExit"/> </widget> <addaction name="menuFile"/> </widget> <widget class="QStatusBar" name="statusbar"/> <action name="actionExit"> <property name="text"> <string>Exit</string> </property> <property name="shortcut"> <string>Ctrl+Q</string> </property> </action> </widget> <resources/> <connections/> </ui> *** bug.cpp #include "bug.h" #include "ui_bug.h" #include <QtCore/QTimer> #include <QtGui/QApplication> #include <QtGui/QPushButton> #include <iostream> #include <boost/format.hpp> using namespace std; using boost::format; MainWindow::MainWindow(void) { _state = 0; _timer = new QTimer(this); _priv = new Ui_MainWindow; _priv->setupUi(this); connect(_priv->actionExit, SIGNAL(triggered()), SLOT(_exit())); connect(_timer, SIGNAL(timeout()), SLOT(_sequence())); _timer->setSingleShot(true); _timer->start(2000); } void MainWindow::_exit(void) { QApplication::closeAllWindows(); } void MainWindow::_sequence(void) { QTreeWidget* treew= _priv->treeWidget; const int nitems= treew->topLevelItemCount(); if (nitems < 1) { cout << "ERROR: no items left" << endl; return; } const int col=1; if (_state==0) { cout << format("adding %d item widgets to column %d\n") % nitems % col; for (int k=0; k < nitems; k++) { QTreeWidgetItem* item= treew->topLevelItem(k); QPushButton* pbut= new QPushButton(item->text(col), this); treew->setItemWidget(item, col, pbut); item->setText(col, ""); } _state+=1; _timer->start(2000); } else if (_state==1) { cout << format("removing %d item widgets from column %d\n") % nitems % col; for (int k=0; k < nitems; k++) { QTreeWidgetItem* item= treew->topLevelItem(k); QPushButton* itemw= dynamic_cast<QPushButton*>(treew->itemWidget(item, col)); item->setText(col, itemw->text()); treew->removeItemWidget(item, col); delete itemw; } _state+=1; _timer->start(2000); } } int main(int ac, char** av) { QApplication app(ac,av); MainWindow gui; gui.show(); return app.exec(); } *** bug.h #ifndef BUG_H #define BUG_H #include <QtGui/QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(void); private slots: void _exit(void); void _sequence(void); private: class Ui_MainWindow* _priv; class QTimer* _timer; int _state; }; #endif *** bug.mk uiparts = bug.ui uihdrs = bug.h sources = bug.cpp target = bug.exe pyuis = $(uiparts:%.ui=ui_%.py) ccuis = $(uiparts:%.ui=ui_%.h) mocs = $(uihdrs:%.h=moc_%.cpp) qtinc = /usr/include/qt4 qtlib = -L/usr/lib/qt4/lib INCL = -I$(qtinc)/QtCore -I$(qtinc)/QtGui -I$(qtinc) LIBS = $(qtlib) -lQtGui -lQtCore .IGNORE: all all: $(pyuis) $(target) $(target): $(mocs) $(sources) $(uihdrs) $(ccuis) g++ -g -o $@ $(INCL) $(mocs) $(sources) $(LIBS) ui_%.py: %.ui pyuic4 -x -o $@ $< ui_%.h: %.ui uic-qt4 -o $@ $< moc_%.cpp: %.h moc-qt4 -o $@ $(INCL) $< -- System Information: Debian Release: squeeze/sid APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.32-5-686 (SMP w/4 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/bash Versions of packages python-qt4 depends on: ii libc6 2.11.2-6 Embedded GNU C Library: Shared lib ii libgcc1 1:4.4.4-8 GCC support library ii libpython2.6 2.6.6-3 Shared Python runtime library (ver ii libqt4-assistant 4:4.6.3-1+b1 Qt 4 assistant module ii libqt4-designer 4:4.6.3-1+b1 Qt 4 designer module ii libqt4-help 4:4.6.3-1+b1 Qt 4 help module ii libqt4-network 4:4.6.3-1+b1 Qt 4 network module ii libqt4-script 4:4.6.3-1+b1 Qt 4 script module ii libqt4-scripttools 4:4.6.3-1+b1 Qt 4 script tools module ii libqt4-svg 4:4.6.3-1+b1 Qt 4 SVG module ii libqt4-test 4:4.6.3-1+b1 Qt 4 test module ii libqt4-webkit 4:4.6.3-1+b1 Qt 4 WebKit module ii libqt4-xml 4:4.6.3-1+b1 Qt 4 XML module ii libqt4-xmlpatterns 4:4.6.3-1+b1 Qt 4 XML patterns module ii libqtcore4 4:4.6.3-1+b1 Qt 4 core module ii libqtgui4 4:4.6.3-1+b1 Qt 4 GUI module ii libstdc++6 4.4.4-8 The GNU Standard C++ Library v3 ii python 2.6.5-13 interactive high-level object-orie ii python-sip [sip-api-7.1] 4.10.2-1 Python/C++ bindings generator runt ii python-support 1.0.10 automated rebuilding support for P python-qt4 recommends no packages. Versions of packages python-qt4 suggests: pn python-qt4-dbg <none> (no description available) -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org