Skip to content

Commit 53c4f13

Browse files
committed
add value slider to value edit
1 parent f8e53e8 commit 53c4f13

File tree

7 files changed

+130
-25
lines changed

7 files changed

+130
-25
lines changed

NodeGraphQt/base/node.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ def add_file_input(self, name, label='', text='', tab=None, ext="*"):
563563
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
564564
self.view.add_widget(widget)
565565

566-
def add_float_input(self, name, label='', value=0.0, tab=None):
566+
def add_float_input(self, name, label='', value=0.0, range=None, tab=None):
567567
"""
568568
Creates a custom property with the :meth:`NodeObject.create_property`
569569
function and embeds a :class:`PySide2.QtWidgets.QLineEdit` widget
@@ -577,15 +577,16 @@ def add_float_input(self, name, label='', value=0.0, tab=None):
577577
name (str): name for the custom property.
578578
label (str): label to be displayed.
579579
value (float): pre filled value.
580+
range (tuple): slider range
580581
tab (str): name of the widget tab to display in.
581582
"""
582583
self.create_property(
583-
name, value, widget_type=NODE_PROP_FLOAT, tab=tab)
584+
name, value, widget_type=NODE_PROP_FLOAT, range=range, tab=tab)
584585
widget = NodeFloatEdit(self.view, name, label, value)
585586
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
586587
self.view.add_widget(widget)
587588

588-
def add_int_input(self, name, label='', value=0, tab=None):
589+
def add_int_input(self, name, label='', value=0, range=None, tab=None):
589590
"""
590591
Creates a custom property with the :meth:`NodeObject.create_property`
591592
function and embeds a :class:`PySide2.QtWidgets.QLineEdit` widget
@@ -599,10 +600,11 @@ def add_int_input(self, name, label='', value=0, tab=None):
599600
name (str): name for the custom property.
600601
label (str): label to be displayed.
601602
value (int): pre filled value.
603+
range (tuple): slider range
602604
tab (str): name of the widget tab to display in.
603605
"""
604606
self.create_property(
605-
name, value, widget_type=NODE_PROP_INT, tab=tab)
607+
name, value, widget_type=NODE_PROP_INT, range=range, tab=tab)
606608
widget = NodeIntEdit(self.view, name, label, value)
607609
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
608610
self.view.add_widget(widget)

NodeGraphQt/widgets/actions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def get_menus(self,node_class):
3939
menus.append(menu)
4040
return menus
4141

42+
4243
class GraphAction(QtWidgets.QAction):
4344

4445
executed = QtCore.Signal(object)

NodeGraphQt/widgets/node_widgets.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ def __init__(self, parent=None, name='', label='', value=0):
325325
self._ledit.set_data_type(int)
326326
self._ledit.setValue(value)
327327

328+
328329
class NodeCheckBox(NodeBaseWidget):
329330
"""
330331
NodeCheckBox widget is subclassed from :class:`NodeBaseWidget`,

NodeGraphQt/widgets/properties.py

Lines changed: 117 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -386,26 +386,26 @@ class _valueEdit(QtWidgets.QLineEdit):
386386
def __init__(self, parent=None):
387387
super(_valueEdit, self).__init__(parent)
388388
self.mid_state = False
389-
self.setValue(0)
390389
self._data_type = float
390+
self.setText("0")
391391

392392
self.pre_x = 0
393393
self._step = 1
394-
self._last_value = 0
395394
self._tmp_value = 0
396395
self._speed = 0.1
397396

398-
self.textChanged.connect(self._on_value_changed)
397+
self.textChanged.connect(self._on_text_changed)
399398

400399
self.menu = _valueMenu()
401400
self.menu.mouseMove.connect(self.mouseMoveEvent)
402401
self.menu.mouseRelease.connect(self.mouseReleaseEvent)
403-
steps = [0.001,0.01,0.1,1,10,100,1000]
402+
steps = [0.001, 0.01, 0.1, 1, 10, 100, 1000]
404403
self.menu.set_steps(steps)
405404

406-
def _on_value_changed(self, text):
405+
self.set_data_type(float)
406+
407+
def _on_text_changed(self, value):
407408
self.valueChanged.emit(self.value())
408-
self._last_value = text
409409

410410
def mouseMoveEvent(self, event):
411411
if self.mid_state:
@@ -445,15 +445,117 @@ def set_data_type(self, dt):
445445
self._data_type = dt
446446
self.menu.set_data_type(dt)
447447

448+
def _convert_text(self,text):
449+
# int("1.0") will return error
450+
# so we use int(float("1.0"))
451+
452+
value = float(text)
453+
if self._data_type is int:
454+
value = int(value)
455+
return value
456+
448457
def value(self):
449458
if self.text().startswith("."):
450459
text = "0"+self.text()
451-
self.setValue(text)
452-
453-
return self._data_type(self.text())
460+
self.setText(text)
461+
return self._convert_text(self.text())
454462

455463
def setValue(self, value):
456-
self.setText(str(value))
464+
if value != self.value():
465+
self.setText(str(self._convert_text(value)))
466+
467+
468+
class _slider(QtWidgets.QSlider):
469+
def __init__(self, parent = None):
470+
super(_slider,self).__init__(parent)
471+
self.setOrientation(QtCore.Qt.Horizontal)
472+
self.setTickPosition(QtWidgets.QSlider.TicksBelow)
473+
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
474+
QtWidgets.QSizePolicy.Preferred)
475+
476+
def _update_value(self,x):
477+
value = (self.maximum() - self.minimum()) * x / self.width() + self.minimum()
478+
self.setValue(value)
479+
480+
def mousePressEvent(self, event):
481+
if event.button() == QtCore.Qt.LeftButton:
482+
self._update_value(event.pos().x())
483+
super(_slider,self).mousePressEvent(event)
484+
485+
486+
class _valueSliderEdit(QtWidgets.QWidget):
487+
valueChanged = QtCore.Signal(object)
488+
489+
def __init__(self, parent=None):
490+
super(_valueSliderEdit, self).__init__(parent)
491+
self._edit = _valueEdit()
492+
self._edit.valueChanged.connect(self._on_edit_changed)
493+
self._edit.setMaximumWidth(70)
494+
self._slider = _slider()
495+
self._slider.valueChanged.connect(self._on_slider_changed)
496+
497+
hbox = QtWidgets.QHBoxLayout()
498+
hbox.addWidget(self._edit)
499+
hbox.addWidget(self._slider)
500+
self.setLayout(hbox)
501+
# self._slider_press_event = self._slider.mousePressEvent
502+
# self._slider.mousePressEvent = self.sliderMousePressEvent
503+
self._mul = 1000.0
504+
self.set_min(0)
505+
self.set_max(10)
506+
self.set_data_type(float)
507+
self._lock = False
508+
509+
def _on_edit_changed(self,value):
510+
if self._lock:
511+
return
512+
self._lock = True
513+
self._set_slider_value(value)
514+
self.valueChanged.emit(self._edit.value())
515+
self._lock = False
516+
517+
def _on_slider_changed(self,value):
518+
value = value / float(self._mul)
519+
self._edit.setValue(value)
520+
521+
def _set_slider_value(self,value):
522+
value = int(value * self._mul)
523+
524+
if value == self._slider.value():
525+
return
526+
527+
_min = self._slider.minimum()
528+
_max = self._slider.maximum()
529+
if _min<=value<=_max:
530+
self._slider.setValue(value)
531+
elif value < _min and self._slider.value() != _min:
532+
self._slider.setValue(_min)
533+
elif value > _max and self._slider.value() != _max:
534+
self._slider.setValue(_max)
535+
536+
def set_min(self, value=0):
537+
self._slider.setMinimum(int(value*self._mul))
538+
539+
def set_max(self, value=10):
540+
self._slider.setMaximum(int(value*self._mul))
541+
542+
def set_data_type(self, dt):
543+
_min = int(self._slider.minimum()/self._mul)
544+
_max = int(self._slider.maximum()/self._mul)
545+
if dt is int:
546+
self._mul = 1.0
547+
elif dt is float:
548+
self._mul = 1000.0
549+
550+
self.set_min(_min)
551+
self.set_max(_max)
552+
self._edit.set_data_type(dt)
553+
554+
def value(self):
555+
return self._edit.value()
556+
557+
def setValue(self,value):
558+
self._edit.setValue(value)
457559

458560

459561
class _doubleSpinBox(QtWidgets.QDoubleSpinBox):
@@ -530,23 +632,22 @@ def __init__(self, parent=None):
530632
super(PropVector4, self).__init__(parent, 4)
531633

532634

533-
class PropFloat(_valueEdit):
635+
class PropFloat(_valueSliderEdit):
534636
value_changed = QtCore.Signal(str, object)
535637

536638
def __init__(self, parent=None):
537639
super(PropFloat, self).__init__(parent)
538640
self.valueChanged.connect(self._on_value_changed)
539641

540-
def _on_value_changed(self):
541-
self.value_changed.emit(self.toolTip(), self.value())
642+
def _on_value_changed(self, value):
643+
self.value_changed.emit(self.toolTip(), value)
542644

543645
def get_value(self):
544646
return self.value()
545647

546648
def set_value(self, value):
547-
if value != self.get_value():
548-
self.setValue(value)
549-
self.value_changed.emit(self.toolTip(), value)
649+
self.setValue(value)
650+
self.value_changed.emit(self.toolTip(), value)
550651

551652

552653
class PropInt(PropFloat):

NodeGraphQt/widgets/scene.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
VIEWER_GRID_OVERLAY,
77
VIEWER_GRID_COLOR)
88

9+
910
class NodeScene(QtWidgets.QGraphicsScene):
1011

1112
def __init__(self, parent=None):

example_auto_nodes/input_nodes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from NodeGraphQt import QtCore
22
from NodeGraphQt.constants import (NODE_PROP_VECTOR2,
33
NODE_PROP_VECTOR3,
4-
NODE_PROP_VECTOR4)
4+
NODE_PROP_VECTOR4,
5+
NODE_PROP_SLIDER)
56

67
from .node_base.auto_node import AutoNode
78
import os
@@ -18,7 +19,7 @@ class FloatInputNode(AutoNode):
1819
def __init__(self):
1920
super(FloatInputNode, self).__init__()
2021
self.output = self.add_output('out', float)
21-
self.add_float_input('out', 'Float Value', value=0.0)
22+
self.add_float_input('out', 'Float Value', value=0.0,range=(-10,10))
2223

2324

2425
class IntInputNode(AutoNode):

example_auto_nodes/node_base/auto_node.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,7 @@ def cook(self, forceCook=False):
9393
try:
9494
self.run()
9595
except Exception as error:
96-
self._autoCook = _tmp
9796
self.error(error)
98-
return
99-
10097
self._autoCook = _tmp
10198

10299
if self.error():
@@ -142,6 +139,7 @@ def set_property(self, name, value):
142139
if name in self.model.custom_properties.keys():
143140
self.cook()
144141

142+
145143
def set_port_type(self, port, value_type):
146144
current_port = None
147145

0 commit comments

Comments
 (0)