如何在QTableView中添加多个QPushButton?

10 投票
2 回答
16937 浏览
提问于 2025-04-18 09:20

我有一个 QTableView,我想在每一行上放一个 QPushButton。我在我的类中这样做,这个类是从 QWidget 继承来的,具体的做法是参考了一个例子,链接在这里 这里

 for index in range(number_rows):
        btn_sell = QPushButton("Edit", self)
        btn_sell.clicked.connect(self.button_edit)
        table_view.setIndexWidget(table_view.model().index(index, 4), btn_sell)

当表格绘制完成后,如果我点击其中一个 QPushButton,就会调用 self.button_edit 这个方法——但我想知道,究竟是哪个按钮被点击了?似乎没有任何“事件”信息传递给 self.button_edit,那么我该如何在 button_edit 方法中找到被点击的 QPushButton 所在的行号呢?

也许还有其他方法可以为表格的每一行添加按钮?

2 个回答

2

创建一个自定义按钮。

class IndexedButtonWidget(QPushButton):
def __init__(self, parent=None):
    super(QPushButton, self).__init__(parent=parent)
    self.button_row = 0
    self.button_column = 0

接下来,创建一个按钮对象。

self.btn_sell = IndexedButtonWidget('Edit')
self.btn_sell.button_row = row
self.btn_sell.button_column = column
self.btn_sell.clicked.connect(self.handleButtonClicked)

def handleButtonClicked(self):
    button = self.sender()
    print(button.button_row)
    print(button.button_column)

示例:

class IndexedButtonWidget(QPushButton):
    def __init__(self, parent=None):
    super(QPushButton, self).__init__(parent=parent)
    self.button_row = 0
    self.button_column = 0

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.table = QtGui.QTableWidget()
        self.table.setColumnCount(3)
        self.setCentralWidget(self.table)
        data1 = ['row1','row2','row3','row4']
        data2 = ['1','2.0','3.00000001','3.9999999']

        self.table.setRowCount(4)

        for index in range(4):
            item1 = QtGui.QTableWidgetItem(data1[index])
            self.table.setItem(index,0,item1)
            item2 = QtGui.QTableWidgetItem(data2[index])
            self.table.setItem(index,1,item2)
            self.btn_sell = IndexedButtonWidget('Edit')
            self.btn_sell.button_row = index
            self.btn_sell.button_column = 2
            self.btn_sell.clicked.connect(self.handleButtonClicked)
            self.table.setCellWidget(index,2,self.btn_sell)

    def handleButtonClicked(self):
        button = self.sender()
        print(button.button_row)
        print(button.button_column)
17

你的事件处理程序看起来会像这样:

def handleButtonClicked(self):
    button = QtGui.qApp.focusWidget()
    # or button = self.sender()
    index = self.table.indexAt(button.pos())
    if index.isValid():
        print(index.row(), index.column())

这里使用了 indexAt 函数来获取按钮的位置。

为了更清楚,我的脚本是这样的:

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.table = QtGui.QTableWidget()
        self.table.setColumnCount(3)
        self.setCentralWidget(self.table)
        data1 = ['row1','row2','row3','row4']
        data2 = ['1','2.0','3.00000001','3.9999999']

        self.table.setRowCount(4)

        for index in range(4):
            item1 = QtGui.QTableWidgetItem(data1[index])
            self.table.setItem(index,0,item1)
            item2 = QtGui.QTableWidgetItem(data2[index])
            self.table.setItem(index,1,item2)
            self.btn_sell = QtGui.QPushButton('Edit')
            self.btn_sell.clicked.connect(self.handleButtonClicked)
            self.table.setCellWidget(index,2,self.btn_sell)

    def handleButtonClicked(self):
        button = QtGui.qApp.focusWidget()
        # or button = self.sender()
        index = self.table.indexAt(button.pos())
        if index.isValid():
            print(index.row(), index.column())

这将生成一个像这样的简单图形界面:

small gui

当点击 Edit 按钮时,它会在控制台打印出:

(0, 2)
(1, 2)
(2, 2)
(3, 2)

第一个元素是你的行索引,第二个是你的列索引(记住这是从0开始的,所以它显示的是2,而不是3——尽管有列标题)。

撰写回答