7

I am new to PyQT.

I am interested to add a combobox to the each row of tableView. Is it possible in PyQT 4?

I know, it is possible in QT5, but not sure about PyQT.

Thank you in advance for help.

Mohammad Saifullah
  • 1,113
  • 5
  • 16
  • 33

3 Answers3

17

If you really want to use QTableView, then it has special method called setIndexWidget and you need only index where you want to put the widget. Small example.

    model = QStandardItemModel (4, 4)
    for row in range(4):
        for column in range(4):
            item = QStandardItem("row %d, column %d" % (row, column))
            model.setItem(row, column, item)

    self.tableView.setModel(model)
    for row in range(4):
        c = QComboBox()
        c.addItems(['cell11','cell12','cell13','cell14','cell15',])
        i = self.tableView.model().index(row,2)
        self.tableView.setIndexWidget(i,c)

Result is similar to the first answer.

Jablonski
  • 18,083
  • 2
  • 46
  • 47
9

Does this need to be done using a QTableView or can you do it using a QTableWidget?

Making the assumption that you can use the Widget vs the View, you can easily add a combobox (or any widget) to a cell.


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']
        combo_box_options = ["Option 1","Option 2","Option 3"]

        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)
            combo = QtGui.QComboBox()
            for t in combo_box_options:
                combo.addItem(t)
            self.table.setCellWidget(index,2,combo)

The important parts here are:

combo_box_options = ["Option 1","Option 2","Option 3"]

This is the list of values you want your combobox to hold. In this example, there are three options.

for t in combo_box_options:
    combo.addItem(t)
self.table.setCellWidget(index,2,combo)

This block sets up the combobox, per row, and then adds it to a cell (the last one in this example).

The code block above produces out put like this:

Table Widget with Drop down

Community
  • 1
  • 1
Andy
  • 49,085
  • 60
  • 166
  • 233
0

Thanks @Kosovan for suggesting setIndexWidget(index, widget) to add widget to qtableview.

In the below code using PySide6 but can easily be modified for PyQt.

To add a widget to QTableView use setIndexWidget

self.tableView.setIndexWidget(self.tableView.model().index(3, 1), QPushButton("Kill"))

self.tableView.setIndexWidget(self.tableView.model().index(3, 2), QFontComboBox())

Source:

#!/usr/bin/env python3.10

import sys
import time

from typing import Union, Any

import PySide6
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QTableView,
                               QPushButton, QFontComboBox)
from PySide6.QtCore import (Qt, QAbstractTableModel)
from PySide6.QtGui import (QColor)


class TableModel(QAbstractTableModel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.values = [["Hello", 2, 5],
                       [22, 55, 6],
                       [2.3, "Kion", time.time()],
                       [2.22, "widget-here", "another-widget-here"]]
        self.initUI()

    def initUI(self):
        pass

    def rowCount(self, index):
        return len(self.values)

    def columnCount(self, index):
        return len(self.values[0])

    def data(self, index: Union[PySide6.QtCore.QModelIndex, PySide6.QtCore.QPersistentModelIndex],
             role: int = ...) -> Any:
        if role == Qt.DisplayRole:
            return self.values[index.row()][index.column()]


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.tableView = QTableView()
        self.tableModel = TableModel()
        self.tableView.setModel(self.tableModel)
        self.tableView.setIndexWidget(self.tableView.model().index(3, 1), QPushButton("Kill"))
        self.tableView.setIndexWidget(self.tableView.model().index(3, 2), QFontComboBox())

        self.setCentralWidget(self.tableView)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    app.exec()

Output:

QTableView with widgets

Udesh
  • 2,415
  • 2
  • 22
  • 32