2012-06-04 83 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