我怎样才能继承 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.selected
、self.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。
首先,我对 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.selected
、self.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。