#!python # -*- mode: python; coding: utf-8 -*- # Last updated: <2016/11/01 15:34:49 +0900> u""" QSliderとQSpinBoxを1つのWidgetにまとめて並べてみるサンプル. RGB/HSLのQSlide + QSpinBoxを用意して値を連動させる。結果を色で表示する。 Windows10 x64 + Python 2.7.11 + PySide 1.2.4 """ import sys from PySide.QtCore import * # NOQA from PySide.QtGui import * # NOQA class LabelSliderSpinBox(QWidget): """Slider and SpinBox.""" # Signalを用意 valueChanged = Signal(int) def __init__(self, text, parent=None): """init.""" super(LabelSliderSpinBox, self).__init__(parent) # self.setContentsMargins(0, 0, 0, 0) hl = QHBoxLayout() hl.setContentsMargins(0, 0, 0, 0) # hl.setSpacing(0) self.lbl = QLabel(text, self) self.sld = QSlider(Qt.Horizontal, self) self.spb = QSpinBox(self) hl.addWidget(self.lbl) hl.addWidget(self.sld) hl.addWidget(self.spb) self.setLayout(hl) self.sld.valueChanged[int].connect(self.changed_slider_value) self.spb.valueChanged[int].connect(self.changed_spinbox_value) # 用意したシグナルとスロットを関連付ける self.valueChanged[int].connect(self.changedValue) def setText(self, text): """set QLabel text.""" self.lbl.setText(text) def setRange(self, start_v, end_v): """set range QSlider and QSpinBox.""" self.sld.setRange(start_v, end_v) self.spb.setRange(start_v, end_v) def setValue(self, value): """set value to QSlider and QSpinBox.""" self.sld.setValue(value) self.spb.setValue(value) def value(self): """get value.""" return self.spb.value() def changed_slider_value(self, n): """changed slider value.""" self.spb.setValue(n) def changed_spinbox_value(self, n): """changed spinbox value.""" self.sld.setValue(n) self.valueChanged.emit(n) # 値が変わったのでシグナルを発行 # スロットを用意する @Slot(int) def changedValue(self, value): """changed slider or spinbox value.""" pass # print("value = %d" % value) class MyWidget(QWidget): """My Widget.""" def __init__(self, *argv, **keywords): """init.""" super(MyWidget, self).__init__(*argv, **keywords) self.setWindowTitle("Color Slider") self.event_ignore = False l = QVBoxLayout() # color display button btn = QPushButton() btn.setFixedSize(64, 64) # set button background-color btn.setStyleSheet("QWidget { background-color: %s }" % QColor(128, 128, 128).name()) l.addWidget(btn) btn.clicked.connect(self.show_color_dialog) self.btn = btn # sliders data = [ ("R", 0, 255, 128), ("G", 0, 255, 128), ("B", 0, 255, 128), ("H", 0, 360, 180), ("S", 0, 255, 128), ("L", 0, 255, 128)] self.sliders = [] for (i, d) in enumerate(data): text, start_v, end_v, init_v = d w = LabelSliderSpinBox(text, self) w.setRange(start_v, end_v) w.setValue(init_v) l.addWidget(w) self.sliders.append(w) if i < 3: w.valueChanged.connect(self.changed_rgb) else: w.valueChanged.connect(self.changed_hsl) self.setLayout(l) def update_rgb_disp(self, col): """update RGB disp button.""" # set background-color self.btn.setStyleSheet("QWidget { background-color: %s }" % col.name()) def set_sliders_rgb(self, col): """set RGB slider value.""" r, g, b = col.red(), col.green(), col.blue() self.set_sliders(0, (r, g, b)) def set_sliders_hsl(self, col): """set HSL slider value.""" h, s, l = col.hslHue(), col.hslSaturation(), col.lightness() self.set_sliders(3, (h, s, l)) def set_sliders(self, idx, v): """set 3 slider value.""" for i in range(3): if self.sliders[idx + i].value() != v[i]: self.sliders[idx + i].setValue(v[i]) def get_sliders(self, idx): """get 3 slider value.""" v = [] for i in range(3): v.append(self.sliders[idx + i].value()) return tuple(v) def changed_rgb(self, _): """changed RGB value.""" if not self.event_ignore: self.event_ignore = True r, g, b = self.get_sliders(0) col = QColor(r, g, b) self.set_sliders_hsl(col) self.update_rgb_disp(col) self.event_ignore = False def changed_hsl(self, _): """changed HSL value.""" if not self.event_ignore: self.event_ignore = True h, s, l = self.get_sliders(3) col = QColor() col.setHsl(h, s, l) self.set_sliders_rgb(col) self.update_rgb_disp(col) self.event_ignore = False def show_color_dialog(self): """open QColorDialog.""" col = QColorDialog.getColor() if col.isValid(): self.set_sliders_rgb(col) def main(): """Main.""" app = QApplication(sys.argv) w = MyWidget() w.show() sys.exit(app.exec_()) if __name__ == '__main__': main()