Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add multiple QPushButtons to a QTableView?

Tags:

python

pyside

I have a QTableView to which I want to set a QPushButton for every row. I am doing this as follows within my class derived from QWidget following an example found here:

 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)

If the table is drawn and I click on one of the QPushButton the method self.button_edit is called - but which one? It does not seem that an 'event' of any sort is given to self.button_edit, so how can I find the row-index of the QPushButton that was clicked within the button_edit method?

Maybe there is a different way altogether to add a button to each row of a table?

like image 736
Alex Avatar asked Jun 10 '14 19:06

Alex


People also ask

Can qpushbutton have stylesheets?

But i want to add a normal QPushButton because QPushButton can have stylesheets. Kindly let me know how to add QPushButton in QTableView.

How do I add a qtableview to a qmainwindow?

You can create a QTableView object and place it inside a QHBoxLayout. Once the QWidget is properly built, pass the object to the QMainWindow as its central widget. Remember that a QTableView needs a model to display information. In this case, you can use a QAbstractTableModel instance.

What is qpushbutton in PyQt?

QPushButton is a simple button in PyQt, when clicked by a user some associated action gets performed. For adding this button into the application, QPushButton class is used. A window having a Push Button, when clicked a message will appear “You clicked Push Button”.

What is the difference between qtableview and qtablewidget?

You could also use the default item model that comes with a QTableWidget instead. QTableWidget is a convenience class that reduces your codebase considerably as you don’t need to implement a data model. However, it’s less flexible than a QTableView, as QTableWidget cannot be used with just any data.


2 Answers

Create a custom button.

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

After that create a button object.

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)

Example:

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)
like image 88
Андрій Назар Avatar answered Oct 21 '22 15:10

Андрій Назар


Your event handler will look similar to this:

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())

This uses the indexAt function to get the button's position.

For clarity, my script looks like this:

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())

Which will produce a small GUI like this:

small gui

When the Edit buttons are clicked, it prints, to the console:

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

The first element is your row index, the second is your column (remember it is 0 based, which is why it shows 2, not 3 - despite the column headers).

like image 24
Andy Avatar answered Oct 21 '22 16:10

Andy