PyQT 中的简单分层列表
我正在尝试创建一个包含 3 列的 UI - 当您在左列中选择一个项目时,所选项目将传递给一个函数,并返回中间列的项目(当然,与在左列中选择项目相同)中间列)
应该很简单,但我找不到任何简单的方法来做到这一点..
我首先尝试了 QColumnView,因为它看起来很完美..但是实现 QAbstractItemModel 似乎过于复杂,并且我找不到任何有用的示例这。
接下来,由于层级数是固定的,所以我制作了三个QListView,并修改了 这个示例 QAbstractListModel
..但是,似乎没有有用的信号可以用来触发层次结构其他级别的更新。根据 PyQT 文档, QListView 仅具有“索引已移动”信号。还有“单击”和“按下”,但是当使用键盘更改项目时,这些不会触发
最后一个选项是 QListWidget,它可以工作,因为它具有所需的信号(itemChanged 等),但是创建列表项的方式有点乏味(将 QListWidgetItem 的父级设置为 QListWidget 实例)
编辑:QListWidget
几乎满足了我的需要:
self.first_column = QListWidget()
self.first_column.itemSelectionChanged.connect(self.update_second_column)
I'm trying to create a UI with 3 columns - when you select an item in the left column, the select item is passed to a function, and it returns the items for the middle column (and of course same for selecting items in the middle column)
Should be simple, but I can't find any easy way to do this..
I first tried QColumnView, as it seemed perfect.. however implementing the QAbstractItemModel seems excessively complicated, and I couldn't find any useful examples of this.
Next, since there is a fixed number of levels, I made three QListView, and modified this example QAbstractListModel
..however there seemed to be no useful signal I could use to trigger the updating of the other levels of the hierarchy. According to the PyQT docs, QListView only has the "indexesMoved" signal. There is also "clicked" and "pressed", however these didn't trigger when changing items with the keyboard
The last options is QListWidget, which would work as it has the required signals (itemChanged etc), but the way list items are created is a bit tedious (making QListWidgetItem with the parent set to the QListWidget instance)
Edit: QListWidget
does pretty much what I need:
self.first_column = QListWidget()
self.first_column.itemSelectionChanged.connect(self.update_second_column)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
任何
QAbastractItemView
都有一个QItemSelectionModel
可通过selectionModel
方法。QItemSelectionModel 有可能对您有帮助的信号:
希望有帮助。
Any
QAbastractItemView
has aQItemSelectionModel
accessible via theselectionModel
method.The QItemSelectionModel has signals that may help you:
Hope it helps.
QListView
继承自QAbstractItemView
(我想你知道这一点),所以它得到 一些信号,希望其中一个(或几个)适合您。这对我有用(在初始化
QMainWindow
或主QWidget
时连接信号,如 SaltyCrane 示例中所示):...
根据模型中的数据类型,您需要选择正确的数据类型来询问
QVariant
为。这里偷偷摸摸的部分是让 QListView 告诉您单击了哪个单元格(即使用
clicked(const QModelIndex&)
与clicked()
) 。我想我花了一些时间查看 Qt4 的 C++ 文档,然后才意识到您可以从信号中获得更多信息。从这里,我会让
handler_slot()
在模型上为第二个QListView
调用setData()
方法(使用由您最初计划使用的功能)。如果我没有完全回答你的问题,我很乐意详细说明。
编辑: 使用箭头键
嗯,没有用于箭头移动的默认
QListView
信号似乎很奇怪,但我们可以制作自己的信号。(对于 Qt4 的信号和槽操作方式来说,这几乎显得不合时宜)
QListView
重新实现了一个方法keyPressEvent(self, QKeyEvent)
,该方法在按下某些键时充当回调函数被压。 您可以阅读更多内容。我们可以用它来获取我们想要的键事件,并发出我们自己的信号。一旦发生按键,我们就会询问 QListView 所选索引 (!) 是什么。当然,您可以选择过滤掉某些键并选择是否处理多个选定的单元格(我认为您可以设置不可能的选择模式,请参阅
QListView
文档)。现在我们已经选择了索引(
QModelIndex
列表),我们将第一个索引(QModelIndex
)与我们的信号一起传递。因为我们在 python 中定义这个信号,所以我们不必设置函数原型;我不知道这是否是一种糟糕的风格。现在您所要做的就是将信号连接到处理程序:
并编写您的处理程序。
我希望这不是一个太令人讨厌的解决方法。
QListView
inherits fromQAbstractItemView
(I think you knew this), so it gets a few signals, hopefully one (or a few) of them works for you.This is working for me (connect signals when initializing your
QMainWindow
or mainQWidget
, as in the SaltyCrane example):...
Depending on the type of data in your model, you'll want to choose the right data type to ask
QVariant
for.The sneaky part here is getting the
QListView
to tell you which cell was clicked (i.e. usingclicked(const QModelIndex&)
vsclicked()
). I think I spent some time looking at the C++ documentation for Qt4 before I realized you could get more out of the signals.From here, I would have the
handler_slot()
call asetData()
method on the model for your secondQListView
(using data generated by the function you originally planned to use).I'd be glad to elaborate if I haven't quite answered your question.
Edit: Working with arrow keys
Hmm, it seems weird that there isn't a default
QListView
signal for arrow movement, but we can make our own.(This almost seems out-of-style for Qt4's signals and slots modus operandi)
QListView
reimplements a methodkeyPressEvent(self, QKeyEvent)
which acts as a callback function when certain keys are pressed. You can read more. We can use this to grab the keyevent(s) that we want, and emit our own signal.Once a keypress occurs, we ask the
QListView
what the selected indices (!) are. Of course, you can choose to filter out certain keys and choose whether to handle multiple selected cells (I think you can set a selection mode where this isn't possible, seeQListView
documentation).Now that we have the selected indices (list of
QModelIndex
), we pass the first one (aQModelIndex
) along with our signal. Because we're defining this signal in python, we don't have to set a function prototype; I have no idea if this is bad style.Now all you have to do is connect the signal to a handler:
and write your handler.
I hope this isn't too nasty of a workaround.