2012-06-04 51 views
3

考虑这样哪些链接使用信号和槽两个滑块的简单示例:PySide(或PyQt的)信号和槽基本

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_()) 

你将如何改变此设置在相反的方向上的第二滑块移动如首先?滑块人会使用这些值来初始化:

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

和Slider其中2使用这些值来初始化:

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

然后stwo的价值将是99 - sone.sliderPosition

你将如何实现信号和插槽,使其工作?我希望能够建立在上面这个简单例子的基础上。

回答

3

你的例子是有点坏了,因为你忘了设置布局的父,也节省滑块控件作为成员属性稍后访问......但是,为了回答你的问题,它真的简单到只是指出你连接到你自己的功能:

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) 

注意如何sliderChanged()具有相同的签名与原始setValue()插槽。您不必将一个小部件直接连接到另一个小部件,而是将其连接到自定义方法,然后将值转换为您想要的值,并按照您的需要操作(在stwo上设置自定义值)。

+0

对不起,这个不好的例子。我只是在学习。我试着运行你的例子,我得到了一个没有滑块(没有错误)的空窗口。然后我发现你编辑了你的答案。现在,当我尝试运行代码时,出现错误“NameError:name'QWidget'未定义”。我会看看我能否弄清楚。顺便说一句,谢谢你有关如何以正确的方式处理这些问题的建议。 – MountainX

+0

得到它的工作。谢谢。 – MountainX

+0

@MountainX:不需要为你的例子道歉。你有一个组织良好的问题。真高兴你做到了! – jdi

3

您可以将信号连接到执行任务的函数。你的代码并不容易做到这一点,并需要重构,所以你可以轻松地做到这一点:

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

这是我做到的。我添加了这个重新实现setValue的类。 (我的主意从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) 

下面是完整的代码。这是一个好方法吗?

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_()) 
+0

您不需要继承子类。只需连接到另一个插槽。利用可以将信号连接到任何方法的事实。我认为使用这种方法的问题是,您正在避免使用Qt类中已有的功能的更简单的途径,以及在不需要时使用子类。将您的小部件保存为实例属性并使用它们。 – jdi

+0

此外,现在你有一个MySlider类,它是简单的硬编码设置其值为'99-int'(int btw阴影内置'int') – jdi

+0

@jdi:好的,谢谢你的回答。 – MountainX