Mohammad Saifullah
Mohammad Saifullah

Reputation: 1143

PyQT4: Adding combobox in Qtableview

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.

Upvotes: 7

Views: 24233

Answers (3)

user8234870
user8234870

Reputation:

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

Upvotes: 0

Jablonski
Jablonski

Reputation: 18504

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.

Upvotes: 17

Andy
Andy

Reputation: 50540

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

Upvotes: 11

Related Questions