まず、私はPythonに比較的慣れておらず、PyQtにも非常に慣れていません。私はオブジェクト指向プログラミングへの最初の一歩を踏み出し、オンラインチュートリアルを見てきましたが、多重継承の問題に悩まされています。
アプリウィンドウでQTableWidgetを作成することを目的としたCreateTable()というクラスがあり、行をクリックするとコンテキストメニューが開き、選択した行をグラフ化するオプションを選択できます。グラフオプションが別のクラスPlotter()に接続されている場合。
私の問題は、グラフをアプリケーションウィンドウに埋め込むためにレイアウト変数を参照する必要があるため、CreateTableがPyQtからQTableWidgetとクラスMainWindowの両方を継承する必要があることです。
継承を試みるための私のコードは次のとおりであり、ここから大いに借用しています。Pythonのsuper()は多重継承でどのように機能しますか?
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__()
主な問題は、グラフをMainWindowレイアウト内に配置しようとしたときです。
self.vboxRight.addWidget(self.Graph)
これがテーブルを作成してプロッタを呼び出すための私のコードです
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はすべてのエラーを例外としてキャッチしているので、エラーに対して取得するのは「プロセスが終了コード1で終了しました」だけです。
私の完全なコードへのさらなる参照が必要な場合は、ここにリンクを提供しました: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クラスでスロットを作成します。これで、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)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加