-3

I am previewing a file in Qtableview and want users to select the column they want to import into a dataframe. this selection is done by listing the column headers in a combobox for easy user selection.

somehow I cannot get the list populated, my code is:


    def Define_Combo(self):
        self.Com_X = QComboBox(self.Combo_X)               
        self.Com_X.clear()
        self.header = self.table.horizontalHeader()     
       # self.header = [self.table.horizontalHeader(self, QHeaderView)]
        self.Com_X.addItems(self.header)

the error I get is:

    self.Com_X.addItems(self.header)

TypeError: addItems(self, Iterable[str]): argument 1 has unexpected type 'QHeaderView'
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Zoner
  • 37
  • 9
  • Your code is a bit confusing. First of all, why are you creating a new QTableView with, from what I can understand, another QTableView as a parent? Then, the `addItems` method of a QComboBox only accepts a list of strings, while you're trying to use the horizontal header, which is a QHeaderView instance. – musicamante Feb 17 '21 at 14:55
  • Sorry, the self.table should be out of the Definition, copy paste error. *Edit, removed '''self.table = QtWidgets.QTableView(self.tableView) '''from example – Zoner Feb 17 '21 at 15:01
  • Is there a way to add column numbers or column headers to the combobox for selecting? – Zoner Feb 17 '21 at 15:06
  • 1
    @Zoner please provide a [mre] – eyllanesc Feb 17 '21 at 15:13

2 Answers2

1

horizontalHeader() (as much as verticalHeader()) returns a QHeaderView class, which is a QWidget that inherits from QAbstractItemView, and that obviously cannot be used as a list of strings, which is what addItems() requires.

If you want to get the list of text headers, you can use the table model's headerData:

    model = self.tableView.model()
    for column in range(model.columnCount()):
        self.Com_X.addItem(model.headerData(column, QtCore.Qt.Horizontal))

Since headers can also be reordered, it's usually better to use the header view instead:

    model = self.tableView.model()
    header = self.tableView.horizontalHeader()
    for column in range(model.columnCount()):
        visualIndex = header.visualIndex(column)
        self.Com_X.addItem(model.headerData(visualIndex, QtCore.Qt.Horizontal))

Capitalized names should only be used for classes and constants, not variables and attributes, so you should better call your combo self.com_X. Read more about this important subject on the official Style Guide for Python Code

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thank you for your help. However, I keep getting the error ``` self.com_x.addItem(model.headerData(column, QtCore.Qt.Horizontal)) TypeError: headerData() missing 1 required positional argument: 'role'``` with your script example, I would like to understand why your example didnt work for me, since it looks way more elegant. Thanks again – Zoner Feb 18 '21 at 03:13
  • Mh, strange, it should have worked without the role, but some model classes don't use the default indeed. Anyway, just add `QtCore.Qt.DisplayRole` as last argument (right after the Horizontal) for both calls of `headerData()`. – musicamante Feb 18 '21 at 07:31
0

this may not be the most elegant solution, but my code now looks like the following:

    def Define_Combo(self):

        self.com_x.clear()
        self.com_y.clear()
        self.com_z.clear()
        model = self.table.model()
        combo_list = []
        for column in range(model.columnCount()):
            combo_list.append(model.index(0, column, self.table.rootIndex()).data()) # for row 0
        self.com_x.addItems(combo_list)
        self.com_y.addItems(combo_list)
        self.com_z.addItems(combo_list)

Another mistake I made was defining my QcomboBox inside the definition

Zoner
  • 37
  • 9