PyQT中的简单分层列表

时间:2011-09-25 06:18:42

标签: user-interface pyqt pyqt4 hierarchy

我正在尝试创建一个包含3列的UI - 当您在左列中选择一个项目时,select项目将传递给一个函数,并返回中间列的项目(当然也会选择相同的项目)中间栏中的项目)

应该很简单,但我找不到任何简单的方法来做到这一点。

我首先尝试了QColumnView,因为它看起来很完美..但是实现QAbstractItemModel似乎过于复杂,我找不到任何有用的例子。

接下来,由于有一定数量的级别,我做了三个QListView,并修改了this example QAbstractListModel

..然而似乎没有任何有用的信号可用于触发更新层次结构的其他级别。根据PyQT文档,QListView只有“indicesMoved”信号。还有“点击”和“按下”,但是用键盘更改项目时没有触发

最后一个选项是QListWidget,它可以工作,因为它具有所需的信号(itemChanged等),但创建列表项的方式有点繁琐(使QListWidgetItem的父设置为QListWidget实例)

编辑:QListWidget完全符合我的需要:

self.first_column = QListWidget()
self.first_column.itemSelectionChanged.connect(self.update_second_column)

2 个答案:

答案 0 :(得分:2)

任何QAbastractItemView都可以通过QItemSelectionModel方法访问selectionModel。 QItemSelectionModel具有可以帮助您的信号:

currentChanged ( const QModelIndex & current, const QModelIndex & previous )
currentColumnChanged ( const QModelIndex & current, const QModelIndex & previous )
currentRowChanged ( const QModelIndex & current, const QModelIndex & previous )
selectionChanged ( const QItemSelection & selected, const QItemSelection & deselected )

希望它有所帮助。

答案 1 :(得分:1)

QListView继承自QAbstractItemView(我认为你知道这一点),所以得到a few signals,希望其中一个(或几个)适合你。

这对我有用(初始化QMainWindow或主QWidget时连接信号,如SaltyCrane示例中所示):

connect(your_list_view, SIGNAL("clicked(const QModelIndex&)"), handler_slot)

...

def handler_slot(idx):
    #idx is a QModelIndex
    #QModelIndex.data() returns a QVariant, Qt4's generic data container
    celldata = idx.data()
    #Choose the proper datatype to ask the QVariant for (e.g. QVariant.toInt())
    actualvalue = celldata.toInt()
    #QVariant.toInt() happens to return a tuple
    print actualvalue[0]

根据模型中的数据类型,您需要choose the right data type to ask QVariant for

此处的鬼祟部分是让QListView告诉您点击了哪个单元格(即使用clicked(const QModelIndex&) vs clicked())。在我意识到你可以从信号中获得更多信息之前,我想我花了一些时间查看Qt4的C ++文档。

从这里开始,我会让handler_slot()在您的第二个setData()模型上调用QListView方法(使用您最初计划使用的函数生成的数据)。

如果我没有完全回答你的问题,我会很高兴。

修改:使用箭头键

嗯,箭头移动没有默认的QListView信号似乎很奇怪,但我们可以制作自己的信号。

(对于Qt4的信号和插槽操作方式,这几乎看起来不合时宜)

QListView重新实现方法keyPressEvent(self, QKeyEvent),当按下某些键时,该方法充当回调函数。 You can read more。我们可以使用它来获取我们想要的关键事件,并发出我们自己的信号。

class ArrowableListView(QListView):
    def keyPressEvent(self, keyevent):
        #Maintain original functionality by calling QListView's version
        QListView.keyPressEvent(self, keyevent)

        #QListView.selectedIndexes returns a list of selected cells, I'm just taking the first one here
        idx = self.selectedIndexes()[0]

        #We'll emit a signal that you can connect to your custom handler
        self.emit(SIGNAL("my_signal"), idx)

一旦按键发生,我们会询问QListView所选索引(!)是什么。当然,您可以选择filter out certain keys并选择是否处理多个选定单元格(我认为您可以设置无法选择的选择模式,请参阅QListView文档)。

现在我们已经选择了索引(QModelIndex列表),我们将第一个(QModelIndex)与我们的信号一起传递。因为我们在python中定义了这个信号,所以不必设置函数原型;我不知道这是不好的风格。

现在你所要做的就是将信号连接到处理程序:

self.connect(your_list_view, SIGNAL("my_signal"), handler_slot)

并编写处理程序。

我希望这不是一个太麻烦的解决方法。