我正在尝试创建一个包含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)
答案 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)
并编写处理程序。
我希望这不是一个太麻烦的解决方法。