QListView选定的索引在嵌入QWidg时未更新

2024-04-27 08:17:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我在QListView的Qwidget中嵌入了一个QPushbutton: QPushbutton>;>;QWidget>;>;QListView

list_widget = QWidget()
list_widget.layout(QHBoxLayout())
btn = QPushButton()
btn.pressed.connect(clicked)
list_widget.layout().addWidget(QPushButton())
list_view.setIndexWidget(self.list_model.index(row, 0), list_widget)

def clicked():
    row = list_view.selectedIndexes()

现在的问题是列表_view.selected索引()按下时不返回按下按钮的行。 这似乎只在QPushbutton直接嵌入到QListView中时起作用:QPushbutton>;>;QListView。你知道吗

有人知道如何将按钮的焦点委托给QListView吗?你知道吗


Tags: gtviewwidget按钮listrowlayoutbtn
1条回答
网友
1楼 · 发布于 2024-04-27 08:17:14

当您单击按钮时,它不会传输到QListView,因为按钮会使用它,并且不会将它传输到其他小部件,因此如果您要获取行,则必须间接获取它,一个可能的解决方案是使用它的几何图形,您必须获取发送者(在本例中是按钮),然后将其从左上方到全局位置,然后将其转换为相对于QListView的视口的本地位置,使用方法indexAt()使用该位置可以得到QModelIndex。你知道吗

from PyQt5 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.list_model = QtGui.QStandardItemModel(200, 1)
        self.list_view = QtWidgets.QListView()
        self.list_view.setModel(self.list_model)
        self.setCentralWidget(self.list_view)

        for row in range(self.list_model.rowCount()):
            list_widget = QtWidgets.QWidget()
            hlay = QtWidgets.QHBoxLayout(list_widget)
            btn = QtWidgets.QPushButton(str(row))
            btn.pressed.connect(self.clicked)
            hlay.addWidget(btn)
            hlay.setContentsMargins(0, 0, 0, 0)
            self.list_view.setIndexWidget(self.list_model.index(row, 0), list_widget)

    @QtCore.pyqtSlot()
    def clicked(self):
        btn = self.sender()
        gp = btn.mapToGlobal(QtCore.QPoint())
        lp = self.list_view.viewport().mapFromGlobal(gp)
        ix = self.list_view.indexAt(lp)
        print("row", ix.row())

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

另一种更简单的方法是使用functools.partial()将行作为参数传递:

from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.list_model = QtGui.QStandardItemModel(200, 1)
        self.list_view = QtWidgets.QListView()
        self.list_view.setModel(self.list_model)
        self.setCentralWidget(self.list_view)

        for row in range(self.list_model.rowCount()):
            list_widget = QtWidgets.QWidget()
            hlay = QtWidgets.QHBoxLayout(list_widget)
            btn = QtWidgets.QPushButton(str(row))
            btn.pressed.connect(partial(self.clicked, row))
            hlay.addWidget(btn)
            hlay.setContentsMargins(0, 0, 0, 0)
            self.list_view.setIndexWidget(self.list_model.index(row, 0), list_widget)

    @QtCore.pyqtSlot(int)
    def clicked(self, row):
        print(row)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

或者使用lambda方法:

from PyQt5 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.list_model = QtGui.QStandardItemModel(200, 1)
        self.list_view = QtWidgets.QListView()
        self.list_view.setModel(self.list_model)
        self.setCentralWidget(self.list_view)

        for row in range(self.list_model.rowCount()):
            list_widget = QtWidgets.QWidget()
            hlay = QtWidgets.QHBoxLayout(list_widget)
            btn = QtWidgets.QPushButton(str(row))
            btn.pressed.connect(lambda *args, row=row: self.clicked(row))
            hlay.addWidget(btn)
            hlay.setContentsMargins(0, 0, 0, 0)
            self.list_view.setIndexWidget(self.list_model.index(row, 0), list_widget)

    @QtCore.pyqtSlot(int)
    def clicked(self, row):
        print(row)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

在我的例子中,我更喜欢使用partials,因为你不需要写很多逻辑,而且它是线程安全的。你知道吗

相关问题 更多 >