我怎样才能继承 QTableWidget 和我的 class MainWindow?

How can I inherit QTableWidget and my class MainWindow?

首先,我对 python 比较陌生,对 PyQt 也很陌生。我正在迈出面向对象编程的第一步,我一直在查看在线教程,但我被多重继承问题困住了。

我 class 调用了 CreateTable() ,其目的是在我的应用程序中创建一个 QTableWidget window,当单击一行时,它会打开一个上下文菜单,然后您可以选择选项绘制所选行。其中图形选项连接到另一个 class Plotter()。

我的问题是 CreateTable 需要继承 PyQt 的 QTableWidget 和我的 class MainWindow,因为我需要引用布局变量才能将我的图表嵌入我的应用程序 window。

我尝试继承的代码如下,大量借鉴自这里:How does Python's super() work with multiple inheritance?

class QTable(QTableWidget):
  def __init__(self):
    super(QTable, self).__init__()
class PassMain(MainWindow):
  def __init__(self):
    super(PassMain, self).__init__()
class PassMainTable(PassMain, QTable):
  def __init__(self):
    super(PassMainTable, self).__init__()

主要问题是当我尝试将图形放置在主窗口布局中时。

self.vboxRight.addWidget(self.Graph) 

这是我创建 table 和调用 plotter

的代码
class CreateTable(PassMainTable): #QTableWidget
def __init__(self, Data, row, col, colHeaders, rowHeaders): #Index, ColumnHeaders
    super(CreateTable, self).__init__()


    self.setSelectionBehavior(self.SelectRows)

    print("Start initialization")
    self.ColHeader = colHeaders
    self.setRowCount(row)
    self.setColumnCount(col)
    self.data = Data
    self.setHorizontalHeaderLabels(colHeaders)

    print("Right before for loop")

    n = len(Data)
    m = len(colHeaders)

    for i in range(n):
        DataValues = self.data.iloc[i,:]
        print("values are {}".format(DataValues))
        #m = len(values)
        ConvertedVals = pd.to_numeric(DataValues)

        ValList = DataValues.values.tolist()
        print(ValList)

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

def contextMenuEvent(self, event):

    menu = QMenu(self)
    graphAction = menu.addAction("Graph")
    compareAction = menu.addAction("Compare")
    scatterAction = menu.addAction("Plot types")
    aboutAction = menu.addAction("about")
    quitAction = menu.addAction("quit")
    printAction = menu.addAction("Print Row")
    action = menu.exec_(self.mapToGlobal(event.pos()))
    if action == quitAction:
        qApp.quit()
    elif action == printAction:
        self.selected = self.selectedItems()
        n = len(self.selected)
        print("n is {}".format(n))
        for i in range(n):
            self.selected[i] = str(self.selected[i].text())
        for i in range(n):
            self.selected[i] = float(self.selected[i])
        print(self.selected)
    elif action == graphAction:
        self.selected = self.selectedItems()
        n = len(self.selected)
        for i in range(n):
            self.selected[i] = str(self.selected[i].text())
        for i in range(n):
            self.selected[i] = float(self.selected[i])
        print("right before plotter called")

        self.Graph = Plotter(self.selected, self.ColHeader)

        self.vboxRight.addWidget(self.Graph)
    else:
        print("u clicked something other than quit")

更糟糕的是,PyQt 将我所有的错误都捕获为异常,所以我得到的所有错误都是 "Process finished with exit code 1"

如果您需要进一步参考我的完整代码,我在此处提供了 link:https://github.com/Silvuurleaf/Data-Analysis-and-Visualization-GUI/blob/master/Plotter3.1.py

谢谢你们能给我的任何帮助。

为了共享数据,不必从小部件继承,只需使用信号,这是 PyQt 中异步共享数据的自然方式。例如,在您的情况下,我们将创建一个名为 dataSignal 的信号,根据您要使用变量 self.selectedself.ColHeader 的代码观察到的情况,第一个类型为 list,第二个 numpy.ndarray 所以我们将构建信号:

class CreateTable(QTableWidget): #QTableWidget
    dataSignal = pyqtSignal(list, np.ndarray)
    def __init__(self, Data, row, col, colHeaders, rowHeaders): #Index, ColumnHeaders
        super(CreateTable, self).__init__()


        self.setSelectionBehavior(self.SelectRows)

        print("Start initialization")
        self.ColHeader = colHeaders
        self.setRowCount(row)
        self.setColumnCount(col)
        self.data = Data
        self.setHorizontalHeaderLabels(colHeaders)

        print("Right before for loop")

        n = len(Data)
        m = len(colHeaders)

        for i in range(n):
            DataValues = self.data.iloc[i,:]
            print("values are {}".format(DataValues))
            #m = len(values)
            ConvertedVals = pd.to_numeric(DataValues)

            ValList = DataValues.values.tolist()
            print(ValList)

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

    def contextMenuEvent(self, event):

        menu = QMenu(self)
        graphAction = menu.addAction("Graph")
        compareAction = menu.addAction("Compare")
        scatterAction = menu.addAction("Plot types")
        aboutAction = menu.addAction("about")
        quitAction = menu.addAction("quit")
        printAction = menu.addAction("Print Row")
        action = menu.exec_(self.mapToGlobal(event.pos()))
        if action == quitAction:
            qApp.quit()
        elif action == printAction:
            self.selected = self.selectedItems()
            n = len(self.selected)
            print("n is {}".format(n))
            for i in range(n):
                self.selected[i] = str(self.selected[i].text())
            for i in range(n):
                self.selected[i] = float(self.selected[i])
            print(self.selected)
        elif action == graphAction:
            self.selected = self.selectedItems()
            n = len(self.selected)
            for i in range(n):
                self.selected[i] = str(self.selected[i].text())
            for i in range(n):
                self.selected[i] = float(self.selected[i])
            print("right before plotter called")

            print(type(self.selected), type(self.ColHeader))
            self.dataSignal.emit(self.selected, self.ColHeader)

        else:
            print("u clicked something other than quit")

然后在 MainWindow class 我们创建一个插槽,在此创建 Plotter 对象并将其添加到布局中。

def dataPlotter(self, x_data,y_data):
    self.Graph = Plotter(x_data, y_data)
    self.vboxRightBottom.addWidget(self.Graph)

为此,我们在创建 CreateTable 对象时连接信号:

self.Table = CreateTable(self.BaseStats, row, col, colHeaders, rowHeaders)
self.Table.dataSignal.connect(self.dataPlotter)
self.vboxRightBottom.addWidget(self.Table)

完整代码为here