【问题标题】:Is it possible to pass a variable of type 'type' to a ComboBox so that all the elements of the collection are selectable?是否可以将“类型”类型的变量传递给组合框,以便集合的所有元素都是可选的?
【发布时间】:2021-02-02 04:16:52
【问题描述】:

我正在尝试创建一个 GUI 应用程序,让我可以针对任何其他变量绘制任何变量。这是我的第一个 GUI 应用程序,所以也许我咬得比我能咀嚼的还多。这些变量的值在数组中,我已经将它们分组到集合中——也就是说,我使用 collections.nametuple 对原始值、计算的幅度和相位、峰值索引和归一化值进行分组(如果例如,我没有使用正确的术语)。

我想要做的是让所有这些变量(或各种集合的元素(?)作为两个组合框 xdata 和 ydata 中的选择,以便我可以针对任何其他变量绘制任何变量。这甚至可能吗?这是我正在尝试创建的应用程序的 MainWindow:

我有文件的选择和数据的解析工作,例如,假设我从文件中的数据创建了这两个集合:

type_aData = collections.namedtuple('type_aData',
                                        'A_RX '
                                        'A_RXlogmag '
                                        'A_RXmag'
                                        'A_RXph'
                                        'A_pkMagInd'
                                        'A_RXlogmag_N'
                                        'A_RXmag_N'
                                        'A_RX_N'
                                        'A_RXph_N')



type_distance = collections.namedtuple('type_distance',
                                     'A'
                                     'B')

每个 A_x 都是一个数组,距离 A 和距离 B 也是如此。我想做类似的事情:

self.xdata.addItem(type_distance)
self.ydata.addItem(type_adata)

这样所有距离变量和 aData 变量都暴露在 x 和 y 数据 ComboBoxes 中,但它抱怨参数不能是“type”类型。如果我改为使用 'type_distance',例如,在引号中,那么我得到的只是 ComboBox 中的文本而不是实际变量(没关系,我仍然不知道如何获取从 ComboBox 中选择的值来处理它——这是下一个障碍!)。

简而言之,我最终希望能够从 x 和 y 数据 ComboBoxes 中选择我想要绘制的变量,以便我可以在函数中使用它们来执行以下操作:

self.data_line=self.graphWidget.plot(self.distance.A, self.aData.A_RX)

self.data_line=self.graphWidget.plot(self.distance.A, self.aData.A_RXph),

例如。

如果有人能指出一些简单的 GUI 应用程序示例,这些应用程序的功能与我在这里尝试做的类似,那就太好了。我不适合这样做 --- 我只是不知道有什么更好的方法。我觉得我这样做的复杂程度超出了它的需要。

【问题讨论】:

  • 打算namedtuple做什么?它创建一个类,即type。您可能想要添加这些类的实例,而不是类本身。
  • "这些变量的值在数组中,我已经将它们分组到集合中——也就是说,我使用 collections.nametuple 对原始值进行分组"你在哪里做呢?
  • @juanpa Gracias 由响应者提供。 collections.namedtuple 中的每个条目都是数组。 A_RX1、A_RXlogmax等,距离也是一样,距离A和距离B都是数组。
  • 我只是想将它们分组到“结构”中,这样​​我就可以在函数之间“传递”结构,而不是每个单独的数组。你能用一个例子解释一下“这些类的实例”是什么意思吗?我不是面向对象的程序员,我仍然不完全理解类、方法等......

标签: python pyqt5 pyqtgraph qcombobox namedtuple


【解决方案1】:

我不确定这是否是您的想法,但这里有一个小示例来说明如何将 namedtuple 的字段添加到 QComboBox 并使用这些组合中当前选择的字段在 matplotlib 图中绘制相应数据的框:

from PyQt5 import QtWidgets
from collections import namedtuple
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np


type_distance = namedtuple('type_aData', ['A_RX', 'A_RXlogmag', 'A_RXmag'])
type_aData = namedtuple('type_aData', ['A', 'B'])


class Widget(QtWidgets.QWidget):

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

        # setup matplotlib figure
        self.figure = Figure()
        self.ax = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self.figure)

        # setup rest of ui
        self.combo_x = QtWidgets.QComboBox(self)
        self.combo_y = QtWidgets.QComboBox(self)
        hlayout = QtWidgets.QHBoxLayout()
        hlayout.addWidget(self.combo_x)
        hlayout.addWidget(self.combo_y)

        vlayout = QtWidgets.QVBoxLayout(self)
        vlayout.addWidget(self.canvas)
        vlayout.addLayout(hlayout)

        # generate some random data
        self.distance, self.data = self.generate_data()

        # add field names of data to comboboxes
        self.combo_x.addItems(self.distance._fields)
        self.combo_y.addItems(self.data._fields)

        # connect signals to slot to automatically update plot when selected fields have changed
        self.combo_x.currentTextChanged.connect(self.plot)
        self.combo_y.currentTextChanged.connect(self.plot)
        self.plot()

    def plot(self):
        # extract field names and corresponding data that should be plotted
        xlabel = self.combo_x.currentText()
        ylabel = self.combo_y.currentText()

        x_data = getattr(self.distance, xlabel)
        y_data = getattr(self.data, ylabel)

        # update plot with newly selected data
        self.ax.clear()
        self.ax.plot(x_data, y_data, 'ro')
        self.ax.set_xlabel(xlabel)
        self.ax.set_ylabel(ylabel)
        self.figure.tight_layout()
        self.canvas.draw()

    def generate_data(self):
        # generate some random data and return data as type_distance and type_aData objects
        npoints = 300
        x_data = np.random.normal(size=npoints)
        y_data_a = np.random.normal(size=npoints)
        y_data_b = np.sin(x_data)

        distance = type_distance(x_data, np.log(np.abs(x_data)), np.abs(x_data))
        data = type_aData(y_data_a, y_data_b)
        return distance, data


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    win = Widget()
    win.show()
    app.exec()

【讨论】:

  • 我认为这正是我想要的。让我试着理解你做了什么。谢谢!
  • 我遇到了第一个障碍。在我的情况下,ydata 是多个命名元组的聚合(假设,例如,有另一种类型 bData,类似于也添加到 y-ComboBox 的 aData;我将如何实现行 y_data = getattr(self.data , ylabel) ?
  • @jrive 您想根据 x 数据的选择更改 y 数据组合框中的条目吗?例如,如果您选择 self.distance.A,那么您是否只想在 y 数据的组合框中看到 self.aData 的字段?
  • 是的,那将非常有用。感谢您的帮助!
猜你喜欢
  • 2022-06-11
  • 2019-03-18
  • 1970-01-01
  • 2016-11-20
  • 2015-03-06
  • 2019-02-09
  • 1970-01-01
  • 2018-09-16
  • 2022-08-18
相关资源
最近更新 更多