Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在PyQtGraph上放大/缩小时从PyQt更新滑块_Python_Pyqt_Pyqt5_Pyqtgraph - Fatal编程技术网

Python 在PyQtGraph上放大/缩小时从PyQt更新滑块

Python 在PyQtGraph上放大/缩小时从PyQt更新滑块,python,pyqt,pyqt5,pyqtgraph,Python,Pyqt,Pyqt5,Pyqtgraph,我想将PyQtGraph鼠标滚轮缩放功能连接到QSlider小部件。因此,当我放大/缩小图形时,我会得到viewbox的范围,滑块窗口应该在滑动范围内跟随。我希望它是什么样子的最接近的例子可以在这个PyQtGraph例子中找到: 因此,我想以某种方式连接以下定义 def update_plot(self): self.axX = self.p6.getAxis('bottom') self.xmin = self.axX.range[0] self.xmax = self

我想将PyQtGraph鼠标滚轮缩放功能连接到QSlider小部件。因此,当我放大/缩小图形时,我会得到viewbox的范围,滑块窗口应该在滑动范围内跟随。我希望它是什么样子的最接近的例子可以在这个PyQtGraph例子中找到:

因此,我想以某种方式连接以下定义

def update_plot(self):
    self.axX = self.p6.getAxis('bottom')
    self.xmin = self.axX.range[0]
    self.xmax = self.axX.range[0]
    print(self.axX.range)
    return xmin, xmax

def update_slider(self, xmin, xmax):
    self.size = self.w1.slider.value()
    self.p6.setXRange(self.xmin+self.size,self.xmax+self.size)
    print(self.size)
然而,我似乎无法让它发挥作用。我在下面附上了我的示例的完整代码。你能帮我什么忙吗

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QLabel, QSizePolicy, QSlider, QSpacerItem, \
    QVBoxLayout, QWidget

import pyqtgraph as pg
import numpy as np


class Slider(QWidget):
    def __init__(self, minimum, maximum, parent=None):
        super(Slider, self).__init__(parent=parent)
        self.verticalLayout = QVBoxLayout(self)
        self.label = QLabel(self)
        self.verticalLayout.addWidget(self.label)
        self.horizontalLayout = QHBoxLayout()
        spacerItem = QSpacerItem(0, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.slider = QSlider(self)
        self.slider.setOrientation(Qt.Vertical)
        self.horizontalLayout.addWidget(self.slider)
        spacerItem1 = QSpacerItem(0, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.resize(self.sizeHint())

        self.minimum = minimum
        self.maximum = maximum
        self.slider.valueChanged.connect(self.setLabelValue)
        self.x = None
        self.setLabelValue(self.slider.value())

    def setLabelValue(self, value):
        self.x = self.minimum + (float(value) / (self.slider.maximum() - self.slider.minimum())) * (
        self.maximum - self.minimum)
        self.label.setText("{0:.4g}".format(self.x))

class Widget(QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent=parent)
        self.horizontalLayout = QHBoxLayout(self)

        # plot (p6)
        self.win = pg.GraphicsWindow(title="Basic plotting examples")
        self.horizontalLayout.addWidget(self.win)
        self.p6 = self.win.addPlot(title="My Plot")
        x = np.arange(1e5)
        self.y1 = np.random.randn(x.size)
        self.p6.plot(self.y1, pen="r")
        self.p6.setMouseEnabled(x=True, y=False)
        self.p6.setXRange(0,300)
        self.p6.setLimits(xMin=0, xMax=len(self.y1))

        self.p6.sigRangeChanged.connect(self.update_plot)

        # slider (w1)
        self.w1 = Slider(0, len(self.y1))
        self.horizontalLayout.addWidget(self.w1)        
        self.w1.slider.setMinimum(0)
        self.w1.slider.setMaximum(len(self.y1))

        self.w1.slider.valueChanged.connect(self.update_slider)

    def update_plot(self):
        self.axX = self.p6.getAxis('bottom')
        self.xmin = self.axX.range[0]
        self.xmax = self.axX.range[0]
        print(self.axX.range)
        return self.xmin, self.xmax


    def update_slider(self, xmin, xmax):
        self.size = self.w1.slider.value()
        self.p6.setXRange(self.xmin+self.size,self.xmax+self.size)
        print(self.size)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

首先,你首先问的问题实际上对StackOverflow的“行为”更有用。编辑之后,您只留下了pyqtgraph示例中无用的纯拷贝/粘贴

不要那样做

人们很少经过编辑,看到你问题的当前状态,他们会认为你根本没有努力解决你的问题(导致他们忽略你的问题)。我建议您撤消编辑,或者至少恢复原始问题示例代码


你的问题的主要问题是缩放不是线性的。从普通用户的角度来看,缩放滑块的每一步都应该增加或减少一个缩放因子(实际上pyqtgraph就是这样做的)

滑块通常是一个线性界面,这意味着它的每一步都应该与它的上一步或下一步成同等比例。
简单地说,如果滑块的“中间步骤”等于图像的原始大小,“下一步”等于图像的两倍大小,则用户希望该步骤旁边的步骤将导致图像大小再次加倍。显然,同样的方法也适用于反向

把它想象成一个旋转框,甚至是一对
+/-
按钮

size=2
印刷品(尺寸)
Out[1]:2
def doZoom(大小、步长):
zoomFactor=2
如果步骤>0:
大小*=缩放因子
其他:
大小/=缩放因子
返回大小
大小=doZoom(大小+1)
印刷品(尺寸)
Out[2]:4
大小=doZoom(大小+1)
印刷品(尺寸)
Out[3]:8
大小=doZoom(大小,-1)
印刷品(尺寸)
Out[4]:4
一个可能的解决方案是实现一个考虑所有这些因素的滑块

import sys
from math import log
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QLabel, QSlider, QWidget, 
    QHBoxLayout, QVBoxLayout)

import pyqtgraph as pg
import numpy as np

class LabelSlider(QWidget):
    def __init__(self, *args, **kwargs):
        super(LabelSlider, self).__init__(*args, **kwargs)
        layout = QVBoxLayout(self)
        # IMPORTANT! QStyles sometimes create *huge* margins (6-10 pixels) around
        # layout contents; we don't really need those in here
        layout.setContentsMargins(0, 0, 0, 0)

        self.label = QLabel()
        layout.addWidget(self.label, alignment=Qt.AlignHCenter)
        # use an arbitrary text for the minimum width to minimize size flickering
        # on value changes
        self.label.setMinimumWidth(self.fontMetrics().width("8.8888e+88"))
        self.label.setAlignment(Qt.AlignCenter)

        layout.addSpacing(10)

        self.slider = QSlider()
        # when adding a QSlider to a QLayout and specifying an alignment, the
        # opposite of the orientation *has* to be omitted to ensure that it's
        # centered in the other direction
        layout.addWidget(self.slider, alignment=Qt.AlignHCenter)
        # set the slider "transparent" for mouse events, so that the user will
        # still see it as enabled but won't be able to interact with it
        self.slider.setAttribute(Qt.WA_TransparentForMouseEvents)

        #set a range high enough to limit rounding errors
        self.slider.setMaximum(100000)

        # expose the basic slider signal/methods for transparency, so that
        # this LabelSlider will have a similar interface to that of a QSlider
        self.value = self.slider.value
        self.valueChanged = self.slider.valueChanged

    def setValue(self, value, xLimit):
        sliderValue = self.slider.maximum() - value * self.slider.maximum()
        self.slider.setValue(sliderValue)

        xLimitMin, xLimitMax = xLimit
        limitRange = xLimitMax - xLimitMin
        floatValue = xLimitMin + (value * limitRange / (limitRange)) * (
            limitRange)
        self.label.setText("{0:.4g}".format(floatValue))
        # ensure that the widget is resized to fit the label contents too;
        # sizeHint will be called afterwards
        self.updateGeometry()

    def sizeHint(self):
        hint = super(LabelSlider, self).sizeHint()
        # adjust the minimum hint width to accomodate the label contents
        if hint.width() < self.label.width():
            hint.setWidth(self.label.width())
        return hint


class Widget(QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent=parent)
        self.horizontalLayout = QHBoxLayout(self)

        self.win = pg.GraphicsWindow(title="Basic plotting examples")
        self.horizontalLayout.addWidget(self.win)
        self.p6 = self.win.addPlot(title="My Plot")
        x = np.arange(1e5)
        self.y1 = np.random.randn(x.size)
        self.p6.plot(self.y1, pen="r")
        self.p6.setMouseEnabled(x=True, y=False)
        self.p6.setXRange(0,300)
        # set a minimum x range for the plot
        # this value *HAS* to be > 0
        self.p6.setLimits(xMin=0, xMax=len(self.y1), minXRange=1)

        self.p6.sigRangeChanged.connect(self.update_plot)

        self.slider = LabelSlider()
        self.horizontalLayout.addWidget(self.slider)

    def update_plot(self):
        state = self.p6.getViewBox().state

        # get the limits of the plot's ViewBox
        limits = state["limits"]
        minZoom, maxZoom = xLimit = limits["xLimits"]
        xRangeMin, xRangeMax = limits["xRange"]

        # if the minimum x range is set, use that instead
        if xRangeMin is not None:
            minZoom = xRangeMin
        # ensure that the minimum x range is > 0
        minZoom = max(1, minZoom)
        if xRangeMax is not None:
            maxZoom = xRangeMax
        xMin, xMax = self.p6.getAxis("bottom").range
        diff = xMax - xMin

        # get the possible minimum and maximum values based on the wheel factor
        factor = abs(state["wheelScaleFactor"])
        minimum = log(maxZoom / 100000., factor)
        maximum = log(minZoom / 100000., factor)
        value = log(diff / 100000., factor)

        # adjust the factor to a 0.0-1.0 range according to the possible zoom
        realValue = (value - minimum) / (maximum - minimum)

        # set the slider value according to the above value
        self.slider.setValue(realValue, xLimit)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
导入系统 从数学导入日志 从PyQt5.QtCore导入Qt 从PyQt5.qtwidts导入(QApplication、QLabel、QSlider、QWidget、, QHBoxLayout,QVBoxLayout) 将pyqtgraph作为pg导入 将numpy作为np导入 类标签滑动器(QWidget): 定义初始化(self,*args,**kwargs): 超级(LabelSlider,self)。\uuuuu初始值(*args,**kwargs) 布局=QVBoxLayout(自身) #重要!QSTYLE有时会在周围创建*巨大*的边距(6-10像素) #版面内容;我们这里真的不需要这些 layout.setContentsMargins(0,0,0,0) self.label=QLabel() layout.addWidget(self.label,alignment=Qt.AlignHCenter) #使用任意文本作为最小宽度以最小化大小闪烁 #论价值变化 self.label.setMinimumWidth(self.fontMetrics().width(“8.8888e+88”)) self.label.setAlignment(Qt.AlignCenter) 布局。添加间距(10) self.slider=QSlider() #将QSlider添加到QLayout并指定路线时 #必须省略方向*的相反方向,以确保 #以另一个方向为中心 layout.addWidget(self.slider,alignment=Qt.AlignHCenter) #为鼠标事件设置滑块“透明”,以便用户 #仍然将其视为已启用,但无法与之交互 self.slider.setAttribute(Qt.WA_TransparentForMouseEvents) #设置足够高的范围以限制舍入误差 self.slider.setMaximum(100000) #公开基本滑块信号/透明度方法,以便 #该标签滑翔机将具有与QSlider类似的接口 self.value=self.slider.value self.valueChanged=self.slider.valueChanged def设置值(自身、值、xLimit): sliderValue=self.slider.max()-value*self.slider.max() self.slider.setValue(sliderValue) xLimitMin,xLimitMax=xLimit limitRange=xLimitMax-xLimitMin floatValue=xLimitMin+(值*限制范围/(限制范围))*( 限制范围) self.label.setText(“{0:.4g}”.format(floatValue)) #确保小部件的大小也能适应标签内容; #之后将调用sizeHint self.updateGeometry() def sizeHint(自身): hint=super(LabelSlider,self).sizeHint() #调整最小提示宽度以适应标签内容 如果hint.width()