[PyKDE] custom QListView

cbrantly at darwin.sfbr.org cbrantly at darwin.sfbr.org
Tue Jun 14 21:15:18 BST 2005


Let me start by saying that I am fairly new to Python and VERY new to PyQt.  
With that being said, the solution to my question is probably very simple.  

I am trying to make a custom QListViewItem that contains QComboBox and 
QLineEdit widgets.  It should operate similar to a QTable, but I need the 
ability to use the tree view feature of the QListView.  I have attached a 
simplified version of my code below.  It seems to be working pretty well, but 
there is one problem that i have not been able to figure out.  

When I resize a column, I want the QComboBox and QLineEdit to be automatically 
resized to fit into that column.  I set a focus proxy for the QComboBox and 
that seems to fix the problem with that widget, but I can't use the same 
solution for the QLineEdit because when I change the focus proxy there is no 
way to edit the text in the QLineEdit.  Right now the QLineEdit will resize 
unless it has the focus (ie. as long as you don't click in it to edit the 
text).

Anyone have a solution to this problem?  I am open to any advice, even if all 
you have to say is that I have gone about this in completely the wrong way!  
Thanks for your help.

-Chad

===============

#!/usr/bin/env python

from qt import *

class ListViewItem(QListViewItem) :

    def __init__(self, parent, text=None) :
        QListViewItem.__init__(self, parent, text)
        self.listView = parent
        self.contents = [] 
        self.data = ''

    def setData(self, item):
        self.data = item
        for c, d in enumerate(self.data):
            self.contents.append(c)
            if type(d)==type([]):
                self.setText(c, d[0])
            else:
                self.setText(c, str(d))

    def paintFocus(self, qPainter, qColorGroup, qRect):

        l, t, r, b = qRect.coords()
        margin = self.listView.itemMargin()
        headeroffset = self.listView.header().sectionRect(0).height()+margin
        t += headeroffset
        b += headeroffset
        
        for c, d in enumerate(self.data):
            
            if type(d)==type([]) and self.isSelected():
                
                if not type(self.contents[c]) == type(QComboBox()):
                    self.contents[c] = QComboBox(self.listView, "ComboBox")
                    self.contents[c].setFocusProxy(self.listView)
                    for i in d:
                        self.contents[c].insertItem(i)

                l = margin + self.listView.header().sectionPos(c)
                r = l + self.listView.header().sectionSize(c) - 1
                qRect.setCoords(l, t, r, b)

                self.contents[c].setGeometry(qRect)
                self.contents[c].show()
            
            elif type(d)==type('') and self.isSelected():
                
                if not type(self.contents[c]) == type(
                    QLineEdit(self.listView, "LineEdit")):
                    self.contents[c] = QLineEdit(self.listView, "LineEdit")
                    self.contents[c].setText(d)

                l = margin + self.listView.header().sectionPos(c)
                r = l + self.listView.header().sectionSize(c) - 1
                qRect.setCoords(l, t, r, b)

                self.contents[c].setGeometry(qRect)
                self.contents[c].show()

        QListViewItem.paintFocus(self, qPainter, qColorGroup, qRect)

    def rtti(self):
        return 1001

    def leave_item(self):
        for c, d in enumerate(self.data):
            if type(d)==type([]):
                self.setText(c, str(self.contents[c].currentText()))
                self.contents[c].hide()
            elif type(d)==type(''):
                self.setText(c, str(self.contents[c].text()))
                self.contents[c].hide()

class ListView(QListView):
    
    def __init__(self, parent=None):
        QListView.__init__(self, parent)
        self.connect(self, SIGNAL('currentChanged( QListViewItem * )'),
            self.item_changed)
        self.previous_item = None
        self.this_item = self.currentItem()
        self.setSorting(-1)
        self.setAllColumnsShowFocus(True)

    def item_changed(self, item):
        self.previous_item = self.this_item
        self.this_item = self.currentItem()
        if not self.previous_item == None:
            self.previous_item.leave_item()

dv = [
[['a','b','c'], ['1', '2', '3'], 'zero'],
[['d','e','f'], ['4', '5', '6'], 'one'],
[['g','h','i'], ['7', '8', '9'], 'two'],
[['j','k','l'], ['10', '11', '12'], 'three'],
[['m','n','o'], ['13', '14', '15'], 'four'],
[['p','q','r'], ['16', '17', '18'], 'five'],
]

if __name__ == "__main__":
    
    import sys
    
    qa = QApplication(sys.argv)
    qlv = ListView()
    qlv.addColumn("a", 200)
    qlv.addColumn("b", 200)
    qlv.addColumn("c", 200)
    
    for item in reversed(dv):
        widget = ListViewItem(qlv, None)
        widget.setData(item)

    qlv.show()
    qa.setMainWidget(qlv)
    qa.exec_loop()




More information about the PyQt mailing list