简体   繁体   English

PySide(或PyQt)信号和插槽基础知识

[英]PySide (or PyQt) signals and slots basics

Consider a simple example like this which links two sliders using signals and slots: 考虑一个这样的简单示例,它使用信号和插槽链接两个滑块:

from PySide.QtCore import *
from PySide.QtGui import *
import sys

class MyMainWindow(QWidget):
 def __init__(self):
  QWidget.__init__(self, None)

  vbox = QVBoxLayout()

  sone = QSlider(Qt.Horizontal)
  vbox.addWidget(sone)

  stwo = QSlider(Qt.Horizontal)
  vbox.addWidget(stwo)

  sone.valueChanged.connect(stwo.setValue)

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

How would you change this so that the second slider moves in the opposite direction as the first? 你会如何改变这一点,以便第二个滑块向与第一个滑块相反的方向移动? Slider one would be initialized with these values: 滑块1将使用以下值初始化:

  sone.setRange(0,99)
  sone.setValue(0)

And slider two would be initialized with these values: 滑块2将使用以下值初始化:

  stwo.setRange(0,99)
  stwo.setValue(99)

And then the value of stwo would be 99 - sone.sliderPosition . 然后stwo的值将是99 - sone.sliderPosition

How would you implement the signal and slot to make this work? 你将如何实现信号和插槽以使其工作? I would appreciate a working example that builds on the simple example above. 我将很感激一个基于上面简单例子的工作示例。

You can connect signals to functions that do things. 您可以将信号连接到执行操作的功能。 Your code isn't structured to do that easily and required refactoring, so you can do it the easy way: 您的代码的结构不是为了轻松完成并需要重构,因此您可以通过简单的方式完成:

stwo.setInvertedAppearance(True)
sone.valueChanged.connect(stwo.setValue)

Your example is a bit broken, because you forgot to set the parent of the layout, and also to save the slider widgets as member attributes to be accessed later... But to answer your question, its really as simple as just pointing your connection to your own function: 你的例子有点坏了,因为你忘了设置布局的父级,并且还将滑块小部件保存为稍后要访问的成员属性...但是要回答你的问题,它就像指向你的连接一样简单对你自己的功能:

class MyMainWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self, None)

        vbox = QVBoxLayout(self)

        self.sone = QSlider(Qt.Horizontal)
        self.sone.setRange(0,99)
        self.sone.setValue(0)
        vbox.addWidget(self.sone)

        self.stwo = QSlider(Qt.Horizontal)
        self.stwo.setRange(0,99)
        self.stwo.setValue(99)
        vbox.addWidget(self.stwo)

        self.sone.valueChanged.connect(self.sliderChanged)

    def sliderChanged(self, val):
        self.stwo.setValue(self.stwo.maximum() - val)

Note how sliderChanged() has the same signature as the original setValue() slot. 请注意sliderChanged()与原始setValue()槽具有相同的签名。 Instead of connecting one widget directly to the other, you connect it to a custom method and then transform the value to what you want, and act how you want (setting a custom value on stwo ) 不是将一个小部件直接连接到另一个小部件,而是将其连接到自定义方法,然后将值转换为您想要的值,并按您的需要运行(在stwo上设置自定义值)

Here's the way I did it. 这就是我做的方式。 I added this class which reimplements setValue. 我添加了这个重新实现setValue的类。 (I got the idea from http://zetcode.com/tutorials/pyqt4/eventsandsignals/ ) (我从http://zetcode.com/tutorials/pyqt4/eventsandsignals/获得了这个想法)

class MySlider(QSlider):
    def __init__(self):
        QSlider.__init__(self, Qt.Horizontal)

    def setValue(self, int):
        QSlider.setValue(self, 99-int)

Here's the complete code. 这是完整的代码。 Is this a good approach? 这是一个好方法吗?

from PySide.QtCore import *
from PySide.QtGui import *
import sys

class MySlider(QSlider):
    def __init__(self):
        QSlider.__init__(self, Qt.Horizontal)

    def setValue(self, int):
        QSlider.setValue(self, 99-int)

class MyMainWindow(QWidget):
 def __init__(self):
  QWidget.__init__(self, None)

  vbox = QVBoxLayout()

  sone = QSlider(Qt.Horizontal)
  sone.setRange(0,99)
  sone.setValue(0)
  vbox.addWidget(sone)

  stwo = MySlider()
  stwo.setRange(0,99)
  stwo.setValue(0)
  vbox.addWidget(stwo)

  sone.valueChanged.connect(stwo.setValue)

  self.setLayout(vbox)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM