Не удается выбрать всю строку данных из QTableWidget

#python-3.x #pyside2 #qtablewidget

#питон #pyqt #pyqt5 #qtableview ( просмотр таблицы ) #qtablewidget — таблица

Вопрос:

Постановка проблемы

Я пытаюсь выбрать строки данных из моего QTableWidget и распечатать их на своей консоли, чтобы я мог протестировать некоторые вещи, с конечной целью — построить график данных. Однако я никогда не смогу захватить всю строку данных.

Фон

Я создал графический интерфейс, который может встраивать несколько QTableWidgets, импортируя специально отформатированный CSV-файл. Цель состоит в том, чтобы иметь возможность извлекать данные из нескольких строк из одной и той же или разных таблиц, а затем отображать их рядом друг с другом. Где каждая строка данных будет представлять собой собственный набор данных и иметь свой собственный график, но на одном и том же рисунке будет несколько графиков.

Для выполнения этой задачи я создал окно CompareWindow, которое открывается при нажатии кнопки Qpushbutton с именем «Сравнить». В окне пользователю предлагается ввести имена таблиц и соответствующие строки из той таблицы, которую они хотят отобразить.

После отправки этой информации у меня есть словарь, на который я могу ссылаться, в котором сохранены все QTableObjects, которые были созданы. Где ключи — это имена, присвоенные таблицам, которые связаны с соответствующим объектом таблицы.

Проблема

Два основных метода, которые я пытался получить данные строки…

Первой идеей было использовать команду TableObject.selectRow(), я бы перебирал нужные мне строки, но всякий раз, когда я это делал, он возвращал nonetype .

Второй метод, который я попробовал, состоял в том, чтобы перебирать столбцы заданных строк, чтобы они заполняли список один за другим, добавляя значения элементов. Однако, когда я сделал это, он только повторно заполнил список одним и тем же номером, который был первой ячейкой в моей Qtable.

Даже когда я явно вызывал определенную строку или столбец, я получал тот же результат. Извлекаемый результат равен .12, число из первой ячейки в моем CSV-файле.

Вот рассматриваемый код, с которым у меня возникли проблемы.

     def initiateMultiPlot(self, tableV, rowV, PlotV):
    """
        1. Match TableName values with the key values in our TableDB
        2. When we find a  match look at that key's corresponding Table Object, and iterate
        through that objects rows and select the rows specified by rowV
        3.Call plot for those values

    """

    #calls my class and creates a blank figure where eventually we will plot data on
    f = CreateFigure.FigureAssembly()
    print("")
    for i in tableV:
        """
            tableV: is list of strings that represent assigned tablenames [Table1, Table2, Table3]
            rowV: is a list, containing lists representing rows from corresponding Tables the user wishes to plot.
                for example [[1,2],[3,4],[1]] means rows 1,2 from table1, rows 3,4 from table2... so on
            PlotV: is a string that is ethier "box" or "whisker" to tell what method to plot. Default right now 
            is to do a simple boxplot
        """
        print("Creating table instance")

        #Table Dictionary is setup so the names of the Tables (tableV) are the keys of the dictionary
        #and the actual table objects are referenced by these keys
        self.TableOBJ = self.TableDictionary[i]
        print("Data Type for the table object is..................{}".format(type(self.TableOBJ)))

        #empty list that will store our row data
        self.Elements = []
        try:
            for rows in rowV:

                for i in rows:
                    print("rowV value is... {}".format(rowV))
                    print("current row list{}".format(rows))
                    print("i value is {}".format(i))
                    print("itterating")

                    for j in range(self.TableOBJ.columnCount()):
                        print("i value is ...{}".format(i))
                        print("j value is .... {}".format(j))

                        #FIRST idea try selecting entire row of data
                        print("i value is ...{}".format(i))
                        print("j value is .... {}".format(j))

                        #entire row returns none-type
                        EntireRow = self.TableOBJ.selectRow(i)
                        print(EntireRow)

                        #selecteditems

                        #SECOND idea try using for loop and iterating through every value in a row
                        item = self.TableOBJ.itemAt(i,j)

                        #explicit call for (row 1, col 1) and  (row 3, col 3), both which output .12
                        print(self.TableOBJ.itemAt(1,1).text())
                        print(self.TableOBJ.itemAt(3,3).text())
                        print("printing item...... {}".format(item))
                        element = item.text()
                        print(element)

                        #list of .12
                        self.Elements.append(element)

                    #elements = [self.TableOBJ.item(i, j).text() for j in range(self.TableOBJ.columnCount()) if
                    #            self.TableOBJ.item(i, j).text() != ""]
                    #print(elements)

        except Exception as e:
            print(e)

        print(self.Elements)
 

Вот моя ссылка на GitHub, содержащая все мои файлы: https://github.com/Silvuurleaf/Data-Visualize-Project

Проблема возникает в моем файле Perspective.py в методе initiateMultiPlot. Файл CompareWindow.py посылает сигнал на мой Perspective.py и подключен к initateMultiPlot. Пожалуйста, поинтересуйтесь, если что-то требует более подробного объяснения.

Комментарии:

1. О, нет, я не видел, спасибо! Я

Ответ №1:

Согласно документации:

QTableWidgetItem *QTableWidget::itemAt(int ax, int ay) const

Возвращает элемент в позиции, эквивалентной QPoint (ax, ay) в системе координат табличного виджета, или возвращает 0, если указанная точка не покрыта элементом в табличном виджете.

То есть возвращает заданные элементы x и y, которые являются графическими координатами относительно QTableWidget , и явно не то, что вы ищете.

Вы должны использовать item() :

QTableWidgetItem *QTableWidget::item(int row, int column) const

Возвращает элемент для данной строки и столбца, если он был установлен; в противном случае возвращает 0.

Но в вашем случае это не сработает, если вы не выполните следующие изменения:

 class CreateTable(QTableWidget):
     ....
            for j in range(0, m):
                self.item = QTableWidgetItem(str(round(ValList[j], 6)))
                # print("{}, {}".format(i, j))
                self.setItem(i, j, self.item)
 

Для:

 class CreateTable(QTableWidget):
     ....
            for j in range(0, m):
                item = QTableWidgetItem(str(round(ValList[j], 6)))
                # print("{}, {}".format(i, j))
                self.setItem(i, j, item)
 

То есть вы меняете свой self.item на item .

Проблема в том, что на первый взгляд ошибка довольно сложная, класс QTableWidget имеет item() функцию, но когда вы используете self.item оператор, который вы заменяете этим вызовом, т.Е. Когда python читает этот оператор, он будет использовать атрибут, а не функцию, поэтому вы получаете ошибку:

Объект TypeError ‘xxx’ не вызывается

Комментарии:

1. Вау, спасибо, я бы никогда этого не понял! Я буду иметь в виду конфликты, которые могут возникнуть в моих соглашениях об именах со встроенными функциями. Когда я изменил свой itemAt (i, j) в моем инициализированном мультиплоте, все остальное работало!

2. ItemAt(x, y) возвращает виджет в соответствии с его геометрическим положением, поэтому при малых значениях x он всегда возвращает один и тот же QTableWidgetItem и, следовательно, один и тот же текст.