2016-07-26 1 views
0

У меня есть ползунок и текстовое поле, содержащее целое число (есть ли выделенное целочисленное поле?) В PyQt5, показанное бок о бок.Синхронизировать значения двух элементов в PyQt5

Мне нужно, чтобы эти два значения были синхронизированы, и то, как я делаю это сейчас, - это QtTimer, и если операторы обнаруживают, что одно значение изменилось совсем недавно, а затем обновили противоположный элемент. Мне сказали, что это было «взломанным», и задавался вопросом, есть ли способ сделать это.

Вы можете увидеть значения текстового поля и ползунки, которые мне нужно синхронизировать в прозрачных областях изображения ниже.

Interface example

ответ

1

Вы можете просто подключить каждый из ползунков к другому, прямо вперед. Я не знаю точной связи между ползунками, но может выглядеть примерно так.

max_player_slider.valueChanged.connect(self.slider1_fu) 
npc_stream_slider.valueChanged.conenct(self.slider2_fu) 

def slider1_fu(self): 
    # do stuff with the npc_stream_slider 

def slider2_fu(self): 
    # do stuff with the max_player_slider 

Редактировать: Вот Tutorial on YouTube, что может быть полезно.

+0

Я думаю @spikespaz просто хочет синхронизировать числовое значение с позиции ползунка – user3419537

+0

@ user3419537 Woops, что вполне возможно. Наверное, я немного перепутал проблему. Однако учебник, который я написал, все еще применяется. – Ian

+0

Да, два набора слайдеров/текстовых полей являются отдельными, но я продолжу и посмотрю учебник, который вы разместили. Спасибо за помощь. – spikespaz

2

Простое решение для подключения valueChanged для каждого ящика слайдер/номер слоту, который синхронизирует значения

self.slider1.valueChanged.connect(self.handleSlider1ValueChange) 
self.numbox1.valueChanged.connect(self.handleNumbox1ValueChange) 

@QtCore.pyqtSlot(int) 
def handleSlider1ValueChange(self, value): 
    self.numbox1.setValue(value) 

@QtCore.pyqtSlot(int) 
def handleNumbox1ValueChange(self.value): 
    self.slider1.setValue(value) 

Лучшее решение для определения пользовательского класса слайдер, который обрабатывает все внутри. Таким образом, вам нужно только обработать синхронизацию один раз.

from PyQt5 import QtCore, QtWidgets 

class CustomSlider(QtWidgets.QWidget): 
    def __init__(self, *args, **kwargs): 
     super(CustomSlider, self).__init__(*args, **kwargs) 
     self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) 
     self.slider.valueChanged.connect(self.handleSliderValueChange) 
     self.numbox = QtWidgets.QSpinBox() 
     self.numbox.valueChanged.connect(self.handleNumboxValueChange) 
     layout = QtWidgets.QHBoxLayout(self) 
     layout.addWidget(self.numbox) 
     layout.addWidget(self.slider) 

    @QtCore.pyqtSlot(int) 
    def handleSliderValueChange(self, value): 
     self.numbox.setValue(value) 

    @QtCore.pyqtSlot(int) 
    def handleNumboxValueChange(self, value): 
     # Prevent values outside slider range 
     if value < self.slider.minimum(): 
      self.numbox.setValue(self.slider.minimum()) 
     elif value > self.slider.maximum(): 
      self.numbox.setValue(self.slider.maximum()) 

     self.slider.setValue(self.numbox.value()) 

app = QtWidgets.QApplication([]) 
slider1 = CustomSlider() 
slider2 = CustomSlider() 
window = QtWidgets.QWidget() 
layout = QtWidgets.QVBoxLayout(window) 
layout.addWidget(slider1) 
layout.addWidget(slider2) 
window.show() 
app.exec_() 

Редактировать: Что касается комментариев от ekhumoro, выше класс может быть упрощена

class CustomSlider(QtWidgets.QWidget): 
    def __init__(self, *args, **kwargs): 
     super(CustomSlider, self).__init__(*args, **kwargs) 
     self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) 
     self.numbox = QtWidgets.QSpinBox() 
     self.numbox.setRange(self.slider.minimum(), self.slider.maximum()) 
     self.slider.valueChanged.connect(self.numbox.setValue) 
     self.slider.rangeChanged.connect(self.numbox.setRange) 
     self.numbox.valueChanged.connect(self.slider.setValue) 
     layout = QtWidgets.QHBoxLayout(self) 
     layout.addWidget(self.numbox) 
     layout.addWidget(self.slider) 

Вы, вероятно, также хотят, чтобы имитировать некоторые из QSlider методов для изменения диапазон и значение. Обратите внимание, что нам не нужно явно указывать что-либо на self.numbox, поскольку связанные с ним соединения с сигналом/слотом позаботятся об этом.

@QtCore.pyqtSlot(int) 
    def setMinimum(self, minval): 
     self.slider.setMinimum(minval) 

    @QtCore.pyqtSlot(int) 
    def setMaximum(self, maxval): 
     self.slider.setMaximum(maxval) 

    @QtCore.pyqtSlot(int, int) 
    def setRange(self, minval, maxval): 
     self.slider.setRange(minval, maxval) 

    @QtCore.pyqtSlot(int) 
    def setValue(self, value): 
     self.slider.setValue(value) 
+0

Ползунок и спинбокс уже имеют необходимые слоты, поэтому вы можете просто выполнить: 'slider.valueChanged.connect (spinbox.setValue)'. Также нет необходимости выполнять какие-либо проверки границ - пользователь * не может * вводить значения за пределами диапазона min/max, заданного на слайдере/спинбонке (что, очевидно, должно быть одинаковым для каждого). – ekhumoro

+0

Я предполагал, что это более общий пример пользовательских слотов, но вы правы, это слишком сложно для этого вопроса. Хорошая точка на проверке границ. Я не думал, что вы можете установить ограничения на спинбокс. Я обновлю свои предложения – user3419537

+0

Ваше решение лучше, чем принятое, потому что оно использует спинбокс. Это действительно упрощает, потому что API-интерфейсы ползунков и спинбокс настолько похожи. Однако ваш примерный код не особо подчеркивает эту упрощенность. – ekhumoro