gpt4 book ai didi

python - 在选项卡之间传递变化的数据

转载 作者:太空宇宙 更新时间:2023-11-03 18:02:26 26 4
gpt4 key购买 nike

我正在尝试构建一个带有两个选项卡的程序。在 Tab1 中,我从图像中选择点坐标 (x,y) 并将其转换为值 self.a。除了图像之外,我在 Tab1 中还有一些其他 UI(即表格)。现在,我想将值 self.a 传递给 Tab2 (不继承所有其他内容)。请记住,当单击新点时,self.a 可以不断更新。

from PySide import QtGui, QtCore
import pandas as pd
import pyqtgraph as pg
import numpy as np
QVariant = lambda value=None: value


class Widget(QtGui.QWidget):

def __init__(self, parent=None):
super().__init__(parent)

v_global_layout = QtGui.QVBoxLayout()
v_global_layout.addWidget(TabDialog())
v_global_layout.setAlignment(QtCore.Qt.AlignTop)

self.setLayout(v_global_layout)


class TabDialog(QtGui.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
tab_widget = QtGui.QTabWidget()

tab_widget.addTab(Tab1(), "1")
tab_widget.addTab(Tab2(), "2")

main_layout = QtGui.QVBoxLayout()
main_layout.addWidget(tab_widget)
self.setLayout(main_layout)


class Tab1(QtGui.QTabWidget):
def __init__(self):
super().__init__()
layout = QtGui.QHBoxLayout()
self.fig = pg.PlotWidget(name='Example: Selecting scatter points')

self.plot_area = self.fig.plotItem
self.a = pg.ScatterPlotItem(pxMode=False)
spots = []
for i in range(10):
for j in range(10):
spots.append({'pos': (1*i, 1*j), 'size': 1, 'pen': {'color': 'w', 'width': 2},
'brush': pg.intColor(i*10+j, 100)})
self.a.addPoints(spots)

self.plot_area.addItem(self.a)

self.a.dataModel = DataFrameModel()
self.a.dataTable = QtGui.QTableView()
self.a.dataTable.setModel(self.a.dataModel)

layout.addWidget(self.a.dataTable)
layout.addWidget(self.fig)
self.setLayout(layout)

self.a.array = np.zeros((0, 2))

def clicked(self, points):
for p in points:
p.setPen('b', width=2)
position = p.viewPos()
self.array = np.append(self.array, np.array([[position.x(), position.y()]]), axis=0)
c = range(len(self.array))
c = list(map(str, c))
self.dataModel.signalUpdate(self.array, columns=c)
self.dataModel.printValues() # also: print(self.array)
self.a.sigClicked.connect(clicked)


class Tab2(QtGui.QTabWidget):
def __init__(self):
super().__init__()
layout = QtGui.QHBoxLayout()

##### Here I want to use Tab1.a and not inherit all the other stuff(layout) #####
#print("values = ", Tab1.a.array) # a should change when a new point is selected in Tab1
#####################################
self.setLayout(layout)


class DataFrameModel(QtCore.QAbstractTableModel):
""" data model for a DataFrame class """
def __init__(self):
super(DataFrameModel, self).__init__()
self.df = pd.DataFrame()

def signalUpdate(self, dataIn, columns):
self.df = pd.DataFrame(dataIn, columns)
self.layoutChanged.emit()

def printValues(self):
print("DataFrame values:\n", self.df.values)

def values(self):
return self.df.values

#------------- table display functions -----------------
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.DisplayRole:
return QVariant()

if orientation == QtCore.Qt.Horizontal:
try:
return self.df.columns.tolist()[section]
except (IndexError, ):
return QVariant()
elif orientation == QtCore.Qt.Vertical:
try:
# return self.df.index.tolist()
return self.df.index.tolist()[section]
except (IndexError, ):
return QVariant()

def data(self, index, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.DisplayRole:
return QVariant()

if not index.isValid():
return QVariant()
return QVariant(str(self.df.ix[index.row(), index.column()]))

def rowCount(self, index=QtCore.QModelIndex()):
return self.df.shape[0]

def columnCount(self, index=QtCore.QModelIndex()):
return self.df.shape[1]


if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)

main_window = Widget()
main_window.setGeometry(100, 100, 640, 480)
main_window.show()

sys.exit(app.exec_())

最佳答案

在这种情况下,您只需使用信号即可完成工作。

在这里,您尝试像访问静态属性一样访问 Tab1.a,但它不是静态属性。理想情况下,我们应该尝试解耦​​不同的小部件。我们应该尽量将他们之间的依赖性降到最低,并将他们视为无知和不了解对方。 TabDialog 可以了解这些小部件中的每一个以及它们之间的连接(在本例中为 Tab1Tab2)。因此,TabDialog 可以负责这些小部件之间的通信。

为此,我们将两个选项卡作为 TabDialog 类的属性,如下所示:

# Have the tabs as this dialog's class properties
self.tab1 = Tab1(image)
self.tab2 = Tab2()

tab_widget.addTab(self.tab1, "1")
tab_widget.addTab(self.tab2, "2")

在 Tab2 类中,我们假设要与 Tab1.a 映射的值是 points_from_tab1_a:

class Tab2(QtGui.QTabWidget):
def __init__(self):
super().__init__()
layout = QtGui.QHBoxLayout()

self.points_from_tab1_a = []
self.setLayout(layout)

现在,在 TabDialog 中,我们将 tab1.asigClicked 信号连接到更新 tab2.points_from_tab1_a< 的方法:

self.tab1.a.sigClicked.connect(self.pointChanged)

def pointChanged(self, points):
tab2.points_from_tab1_a = tab1.a

这应该可以解决问题。因此,经过这些更改后,您的完整代码片段将如下所示:

from PySide import QtGui, QtCore
import pandas as pd
import pyqtgraph as pg
import numpy as np
QVariant = lambda value=None: value


class Widget(QtGui.QWidget):

def __init__(self, parent=None):
super().__init__(parent)

v_global_layout = QtGui.QVBoxLayout()
v_global_layout.addWidget(TabDialog())
v_global_layout.setAlignment(QtCore.Qt.AlignTop)

self.setLayout(v_global_layout)


class TabDialog(QtGui.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
tab_widget = QtGui.QTabWidget()

# Have the tabs as this dialog's class properties
self.tab1 = Tab1(image)
self.tab2 = Tab2()

tab_widget.addTab(self.tab1, "1")
tab_widget.addTab(self.tab2, "2")

self.tab1.a.sigClicked.connect(self.pointChanged)

main_layout = QtGui.QVBoxLayout()
main_layout.addWidget(tab_widget)
self.setLayout(main_layout)

def pointChanged(self, points):
tab2.points_from_tab1_a = tab1.a


class Tab1(QtGui.QTabWidget):
def __init__(self):
super().__init__()
layout = QtGui.QHBoxLayout()
self.fig = pg.PlotWidget(name='Example: Selecting scatter points')

self.plot_area = self.fig.plotItem
self.a = pg.ScatterPlotItem(pxMode=False)
spots = []
for i in range(10):
for j in range(10):
spots.append({'pos': (1*i, 1*j), 'size': 1, 'pen': {'color': 'w', 'width': 2},
'brush': pg.intColor(i*10+j, 100)})
self.a.addPoints(spots)

self.plot_area.addItem(self.a)

self.a.dataModel = DataFrameModel()
self.a.dataTable = QtGui.QTableView()
self.a.dataTable.setModel(self.a.dataModel)

layout.addWidget(self.a.dataTable)
layout.addWidget(self.fig)
self.setLayout(layout)

self.a.array = np.zeros((0, 2))

def clicked(self, points):
for p in points:
p.setPen('b', width=2)
position = p.viewPos()
self.array = np.append(self.array, np.array([[position.x(), position.y()]]), axis=0)
c = range(len(self.array))
c = list(map(str, c))
self.dataModel.signalUpdate(self.array, columns=c)
self.dataModel.printValues() # also: print(self.array)
self.a.sigClicked.connect(clicked)


class Tab2(QtGui.QTabWidget):
def __init__(self):
super().__init__()
layout = QtGui.QHBoxLayout()

self.points_from_tab1_a = []
##### Here I want to use Tab1.a and not inherit all the other stuff(layout) #####
#print("values = ", Tab1.a.array) # a should change when a new point is selected in Tab1
#####################################
self.setLayout(layout)


class DataFrameModel(QtCore.QAbstractTableModel):
""" data model for a DataFrame class """
def __init__(self):
super(DataFrameModel, self).__init__()
self.df = pd.DataFrame()

def signalUpdate(self, dataIn, columns):
self.df = pd.DataFrame(dataIn, columns)
self.layoutChanged.emit()

def printValues(self):
print("DataFrame values:\n", self.df.values)

def values(self):
return self.df.values

#------------- table display functions -----------------
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.DisplayRole:
return QVariant()

if orientation == QtCore.Qt.Horizontal:
try:
return self.df.columns.tolist()[section]
except (IndexError, ):
return QVariant()
elif orientation == QtCore.Qt.Vertical:
try:
# return self.df.index.tolist()
return self.df.index.tolist()[section]
except (IndexError, ):
return QVariant()

def data(self, index, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.DisplayRole:
return QVariant()

if not index.isValid():
return QVariant()
return QVariant(str(self.df.ix[index.row(), index.column()]))

def rowCount(self, index=QtCore.QModelIndex()):
return self.df.shape[0]

def columnCount(self, index=QtCore.QModelIndex()):
return self.df.shape[1]


if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)

main_window = Widget()
main_window.setGeometry(100, 100, 640, 480)
main_window.show()

sys.exit(app.exec_())

您可以使用信号和槽的概念随意更改它以满足您的需求。希望这有用。

关于python - 在选项卡之间传递变化的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27469654/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com