当多个小部件共享同一个回调时识别源小部件

时间:2017-06-02 12:02:05

标签: python pyqt pyqt5

我在循环中创建多个小部件,它们都共享相同的回调。我的问题是识别触发回调的小部件。

我尝试将小部件的索引作为回调的参数,如下所示:

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QSlider, QVBoxLayout, QWidget
import sys

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

    self.sliders = []
    for n in range(10):
      slider = QSlider(Qt.Horizontal)
      slider.valueChanged.connect(lambda: self.on_slider(n))
      self.sliders.append(slider)

    layout = QVBoxLayout()
    for slider in self.sliders:
      layout.addWidget(slider)
    self.setLayout(layout)

  def on_slider(self, n):
    print(n)


app = QApplication(sys.argv)
gui = Foo()
gui.show()
sys.exit(app.exec())

然而,这会为任何移动的滑块打印9

1 个答案:

答案 0 :(得分:1)

要获得哪个对象发出信号,有几种形式,如:

  1. 您必须首先传递返回信号的参数,然后传递其他参数。
  2. slider.valueChanged.connect(lambda val, n=n: self.on_slider(val, n))
    
    [...]
    
    def on_slider(self, val, n):
        print(n, val)
    

    完整代码:

    class Foo(QWidget):
      def __init__(self, parent=None):
        super().__init__(parent)
    
        self.sliders = []
        for n in range(10):
          slider = QSlider(Qt.Horizontal)
          slider.valueChanged.connect(lambda val, n=n: self.on_slider(val, n))
          self.sliders.append(slider)
    
        layout = QVBoxLayout()
        for slider in self.sliders:
          layout.addWidget(slider)
        self.setLayout(layout)
    
      def on_slider(self, val, n):
        print(n)
    

    2-另一种方法是使用objectNamesetObjectName以及返回发出信号的对象的sender函数。

    for n in range(10):
          slider = QSlider(Qt.Horizontal)
          slider.setObjectName(str(n))
          slider.valueChanged.connect(self.on_slider)
    
    [...]
    
    def on_slider(self, val):
        print(self.sender().objectName(), val)
    

    完整代码:

    class Foo(QWidget):
      def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout(self)
    
        for n in range(10):
          slider = QSlider(Qt.Horizontal)
          slider.setObjectName(str(n))
          slider.valueChanged.connect(self.on_slider)
          layout.addWidget(slider)
    
      def on_slider(self, val):
        print(self.sender().objectName(), val)