[PyKDE] ListView weirdness

Geoff Gerrietts geoff at gerrietts.net
Wed May 14 22:30:01 BST 2003


I've been working on a little app that uses a listview on the left to
select an item, while an edit panel on the right lets me modify its
attributes. I think it's a fairly common interface idiom, seen quite a
bit in configuration screens and the like.

My difficulty started when I wanted to add a confirm dialog. I wanted
it so that if you selected a new item while changes were still
pending, you'd get a dialog saying "Discard changes?" Again, a fairly
common UI idiom.

My idea was, when I caught a selectionChanged() signal, I would raise
the dialog. If I got "ok", I would update the edit panel and discard
the changes. If I got anything else, I would reset the selection to
the previous value. To facilitate this, I set it up so that if the
same item was selected twice, I would return immediately.

Conceptually, this seems sound. I catch the signal, discover it's
going to discard changes, warn the user. When the user says "whoops" I
reset the selection, and when my slot catches the new event, it
returns immediately because that's what's already selected. Printing
out the "selectionTree.selectedItem()" before the return should result
in:  new, old.

Instead, I get the warning dialog twice. The printout shows new, old,
new, old.

I have no idea where this second event is coming from, but I know
(based on strategic commenting) it's related to the call to
setSelected() in the handler. What am I doing wrong?

Sample code that illustrates the case is below -- it's not the actual
app, but it reproduces the erroneous behavior. I can send the actual
app to anyone interested in seeing the whole thing, but it's still
very much a work in progress.

Thanks,
--G.

-- 
Geoff Gerrietts                  "If programming langauges were porn,
<geoff at gerrietts net>                       Java would be bukkake." 
http://www.gerrietts.net                        --Dan Dillinger


from qt import *

data = { 
    'fruit': ['apple', 'banana', 'cherry'], 
    'animal': ['ant', 'bear', 'cat']
}

class NoteEditor(QDialog):
    selectedItem = None

    def __init__(self,parent = None,name = None,modal = 0,fl = 0):
        QDialog.__init__(self,parent,name,modal,fl)

        if name == None:
            self.setName("ListMadness!")

        self.resize(146,480)
        self.setCaption(self.trUtf8("Note Editor"))

        seltree = self.selectionTree = QListView(self,"selectionTree")
        seltree.addColumn(self.trUtf8("Topics"))
        seltree.header().setClickEnabled(0,seltree.header().count() - 1)
        seltree.setGeometry(QRect(4,10,130,460))

        for category, topics in data.items():
            cat_item = QListViewItem(seltree, category)
            for topic in topics:
                top_item = QListViewItem(cat_item, topic)
                if self.selectedItem is None:
                    seltree.setSelected(top_item, 1)
                    self.selectedItem = top_item
            cat_item.setOpen(1)

        self.connect(self.selectionTree,SIGNAL("selectionChanged(QListViewItem*)"),self.refreshActiveTopic)


    def refreshActiveTopic(self):
        currentListItem = self.selectionTree.selectedItem()
        print "currentListItem", currentListItem
        print "self.selectedItem", self.selectedItem

        if currentListItem == self.selectedItem:
            return

        res = QMessageBox.warning(self,
            "Are you sure?",
            "Are you sure you really want to change topics?",
            QMessageBox.Ok, QMessageBox.Cancel)
        if res != 1:
            self.selectionTree.setSelected(self.selectedItem,1)
        else:
            self.selectedItem = currentListItem

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    app.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()'))
    w = NoteEditor()
    w.show()
    app.exec_loop()




More information about the PyQt mailing list