Skip to content

Commit 5813e25

Browse files
committed
add new property widgets:float,int,vector
1 parent 2d72cae commit 5813e25

File tree

9 files changed

+274
-85
lines changed

9 files changed

+274
-85
lines changed

NodeGraphQt/base/node.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
NODE_PROP_QCOMBO,
99
NODE_PROP_QCHECKBOX,
1010
IN_PORT, OUT_PORT,
11-
NODE_PROP_FILE)
11+
NODE_PROP_FILE,
12+
NODE_PROP_FLOAT,
13+
NODE_PROP_INT)
1214
from NodeGraphQt.errors import PortRegistrationError
1315
from NodeGraphQt.qgraphics.node_backdrop import BackdropNodeItem
1416
from NodeGraphQt.qgraphics.node_base import NodeItem
1517
from NodeGraphQt.widgets.node_widgets import (NodeComboBox,
1618
NodeLineEdit,
1719
NodeFloatEdit,
20+
NodeIntEdit,
1821
NodeCheckBox,
1922
NodeFilePath)
2023

@@ -529,10 +532,8 @@ def add_text_input(self, name, label='', text='', tab=None, multi_line=False):
529532
tab (str): name of the widget tab to display in.
530533
multi_line (bool): if create multi line property.
531534
"""
532-
if multi_line:
533-
wid_type = NODE_PROP_QTEXTEDIT
534-
else:
535-
wid_type = NODE_PROP_QLINEEDIT
535+
wid_type = NODE_PROP_QTEXTEDIT if multi_line else NODE_PROP_QLINEEDIT
536+
536537
self.create_property(
537538
name, text, widget_type=wid_type, tab=tab)
538539
widget = NodeLineEdit(self.view, name, label, text)
@@ -579,11 +580,33 @@ def add_float_input(self, name, label='', value=0.0, tab=None):
579580
tab (str): name of the widget tab to display in.
580581
"""
581582
self.create_property(
582-
name, value, widget_type=NODE_PROP_QLINEEDIT, tab=tab)
583+
name, value, widget_type=NODE_PROP_FLOAT, tab=tab)
583584
widget = NodeFloatEdit(self.view, name, label, value)
584585
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
585586
self.view.add_widget(widget)
586587

588+
def add_int_input(self, name, label='', value=0, tab=None):
589+
"""
590+
Creates a custom property with the :meth:`NodeObject.create_property`
591+
function and embeds a :class:`PySide2.QtWidgets.QLineEdit` widget
592+
into the node.
593+
594+
Note:
595+
The embedded widget is wired up to the :meth:`NodeObject.set_property`
596+
function use this function to to update the widget.
597+
598+
Args:
599+
name (str): name for the custom property.
600+
label (str): label to be displayed.
601+
value (int): pre filled value.
602+
tab (str): name of the widget tab to display in.
603+
"""
604+
self.create_property(
605+
name, value, widget_type=NODE_PROP_INT, tab=tab)
606+
widget = NodeIntEdit(self.view, name, label, value)
607+
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
608+
self.view.add_widget(widget)
609+
587610
def add_checkbox(self, name, label='', text='', state=False, tab=None):
588611
"""
589612
Creates a custom property with the :meth:`NodeObject.create_property`

NodeGraphQt/constants.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@
7171
NODE_PROP_SLIDER = 9
7272
#: Property type represented with a file selector widget in the properties bin.
7373
NODE_PROP_FILE = 10
74+
#: Property type represented with a vector2 widget in the properties bin.
75+
NODE_PROP_VECTOR2 = 11
76+
#: Property type represented with vector3 widget in the properties bin.
77+
NODE_PROP_VECTOR3 = 12
78+
#: Property type represented with vector4 widget in the properties bin.
79+
NODE_PROP_VECTOR4 = 13
80+
#: Property type represented with float widget in the properties bin.
81+
NODE_PROP_FLOAT = 14
82+
#: Property type represented with int widget in the properties bin.
83+
NODE_PROP_INT = 15
7484

7585
# === NODE VIEWER ===
7686

NodeGraphQt/widgets/node_widgets.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,7 @@ class NodeFloatEdit(NodeLineEdit):
274274

275275
def __init__(self, parent=None, name='', label='', value=0.0):
276276
super(NodeFloatEdit, self).__init__(parent, name, label)
277-
regex = '\\d+|\\d+\\.\\d+'
278-
validator = QtGui.QRegExpValidator(regex, self._ledit)
279-
self._ledit.setValidator(validator)
277+
self._ledit.setValidator(QtGui.QDoubleValidator())
280278
self.text = str(value)
281279
self._ledit.setText(self.text)
282280

@@ -288,12 +286,41 @@ def value(self):
288286
Returns:
289287
float: float value.
290288
"""
291-
try:
292-
value = float(self._ledit.text())
293-
except:
294-
value = 0.0
295-
self._ledit.setText(str(value))
289+
value = float(self._ledit.text())
290+
return value
291+
292+
@value.setter
293+
def value(self, text=0.0):
294+
if text != self.value:
295+
self._ledit.setText(str(text))
296+
self._value_changed()
297+
298+
299+
class NodeIntEdit(NodeLineEdit):
300+
"""
301+
NodeIntEdit widget is subclassed from :class:`NodeLineEdit`,
302+
this widget is displayed as a ``QLineEdit`` embedded in a node.
303+
304+
.. note::
305+
`To embed a ``QLineEdit`` in a node see func:`
306+
:meth:`NodeGraphQt.BaseNode.add_float_input`
307+
"""
308+
309+
def __init__(self, parent=None, name='', label='', value=0.0):
310+
super(NodeIntEdit, self).__init__(parent, name, label)
311+
self._ledit.setValidator(QtGui.QIntValidator())
312+
self.text = str(value)
313+
self._ledit.setText(self.text)
296314

315+
@property
316+
def value(self):
317+
"""
318+
Returns the widgets current int value.
319+
320+
Returns:
321+
int: int value.
322+
"""
323+
value = int(self._ledit.text())
297324
return value
298325

299326
@value.setter

NodeGraphQt/widgets/properties.py

Lines changed: 124 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
NODE_PROP_QSPINBOX,
1111
NODE_PROP_COLORPICKER,
1212
NODE_PROP_SLIDER,
13-
NODE_PROP_FILE)
13+
NODE_PROP_FILE,
14+
NODE_PROP_VECTOR2,
15+
NODE_PROP_VECTOR3,
16+
NODE_PROP_VECTOR4,
17+
NODE_PROP_FLOAT,
18+
NODE_PROP_INT)
1419
from NodeGraphQt.widgets.file_dialog import file_dialog
1520

1621

@@ -68,8 +73,6 @@ def __init__(self, parent=None):
6873
layout.addWidget(self._label, 0, QtCore.Qt.AlignCenter)
6974
layout.addWidget(self._button, 1, QtCore.Qt.AlignLeft)
7075

71-
self._label.setStyleSheet('QLabel {color: rgba(255, 255, 255, 150);}')
72-
7376
def _on_select_color(self):
7477
color = QtWidgets.QColorDialog.getColor(QtGui.QColor(*self.get_value()),options=QtWidgets.QColorDialog.ShowAlphaChannel)
7578
if color.isValid():
@@ -180,22 +183,10 @@ class PropLineEdit(QtWidgets.QLineEdit):
180183

181184
def __init__(self, parent=None):
182185
super(PropLineEdit, self).__init__(parent)
183-
self.__prev_text = ''
184-
self.editingFinished.connect(self._on_return_pressed)
185-
186-
def focusInEvent(self, event):
187-
super(PropLineEdit, self).focusInEvent(event)
188-
self.__prev_text = self.text()
186+
self.editingFinished.connect(self._on_editing_finished)
189187

190-
def focusOutEvent(self, event):
191-
super(PropLineEdit, self).focusOutEvent(event)
192-
if self.__prev_text != self.text():
193-
self.value_changed.emit(self.toolTip(), self.text())
194-
self.__prev_text = ''
195-
196-
def _on_return_pressed(self):
197-
if self.__prev_text != self.text():
198-
self.value_changed.emit(self.toolTip(), self.text())
188+
def _on_editing_finished(self):
189+
self.value_changed.emit(self.toolTip(), self.text())
199190

200191
def get_value(self):
201192
return self.text()
@@ -225,9 +216,6 @@ def focusOutEvent(self, event):
225216
self.value_changed.emit(self.toolTip(), self.toPlainText())
226217
self.__prev_text = ''
227218

228-
def _on_return_pressed(self):
229-
self.value_changed.emit(self.toolTip(), self.get_value())
230-
231219
def get_value(self):
232220
return self.toPlainText()
233221

@@ -350,6 +338,115 @@ def set_value(self, value):
350338
self._on_value_change(_value)
351339

352340

341+
class PropVector(BaseProperty):
342+
def __init__(self, parent=None,dim=3):
343+
super(PropVector, self).__init__(parent)
344+
hbox = QtWidgets.QHBoxLayout()
345+
self._value = []
346+
self._items = []
347+
348+
for i in range(dim):
349+
self._add_item(i, hbox)
350+
351+
self._can_emit = True
352+
self.setLayout(hbox)
353+
354+
def _add_item(self,index,hbox):
355+
_ledit = QtWidgets.QLineEdit()
356+
_ledit.index = index
357+
_ledit.setText("0")
358+
_ledit.setAlignment(QtCore.Qt.AlignLeft)
359+
_ledit.editingFinished.connect(lambda: self._on_value_change(_ledit.text(), _ledit.index))
360+
_ledit.setValidator(QtGui.QDoubleValidator())
361+
_ledit.setStyleSheet("QLineEdit{border:1px solid}")
362+
363+
hbox.addWidget(_ledit)
364+
self._value.append(0.0)
365+
self._items.append(_ledit)
366+
367+
def _on_value_change(self, value=None,index=None):
368+
if self._can_emit:
369+
if index is not None:
370+
self._value[index] = float(value)
371+
372+
self.value_changed.emit(self.toolTip(), self._value)
373+
374+
def _update_items(self):
375+
for index ,value in enumerate(self._value):
376+
if float(self._items[index].text()) != value:
377+
self._items[index].setText(str(value))
378+
379+
def get_value(self):
380+
return self._value
381+
382+
def set_value(self, value):
383+
if value != self.get_value():
384+
self._value = value.copy()
385+
self._can_emit = False
386+
self._update_items()
387+
self._can_emit = True
388+
self._on_value_change()
389+
390+
391+
class PropVector2(PropVector):
392+
def __init__(self,parent=None):
393+
super(PropVector2,self).__init__(parent,2)
394+
395+
396+
class PropVector3(PropVector):
397+
def __init__(self,parent=None):
398+
super(PropVector3,self).__init__(parent,3)
399+
400+
401+
class PropVector4(PropVector):
402+
def __init__(self,parent=None):
403+
super(PropVector4,self).__init__(parent,4)
404+
405+
406+
class PropFloat(QtWidgets.QLineEdit):
407+
408+
value_changed = QtCore.Signal(str, object)
409+
410+
def __init__(self, parent=None):
411+
super(PropFloat, self).__init__(parent)
412+
self.setText("0.0")
413+
self.setValidator(QtGui.QDoubleValidator())
414+
self.editingFinished.connect(self._on_editing_finished)
415+
416+
def _on_editing_finished(self):
417+
self.value_changed.emit(self.toolTip(), float(self.text()))
418+
419+
def get_value(self):
420+
return float(self.text())
421+
422+
def set_value(self, value):
423+
if value != self.get_value():
424+
self.setText(str(value))
425+
self.value_changed.emit(self.toolTip(), value)
426+
427+
428+
class PropInt(QtWidgets.QLineEdit):
429+
430+
value_changed = QtCore.Signal(str, object)
431+
432+
def __init__(self, parent=None):
433+
super(PropInt, self).__init__(parent)
434+
self.setText("0")
435+
self.setValidator(QtGui.QIntValidator())
436+
self.editingFinished.connect(self._on_editing_finished)
437+
438+
def _on_editing_finished(self):
439+
self.value_changed.emit(self.toolTip(), int(self.text()))
440+
441+
def get_value(self):
442+
return int(self.text())
443+
444+
def set_value(self, value):
445+
if value != self.get_value():
446+
self.setText(str(value))
447+
self.value_changed.emit(self.toolTip(), value)
448+
449+
353450
WIDGET_MAP = {
354451
NODE_PROP_QLABEL: PropLabel,
355452
NODE_PROP_QLINEEDIT: PropLineEdit,
@@ -359,7 +456,12 @@ def set_value(self, value):
359456
NODE_PROP_QSPINBOX: PropSpinBox,
360457
NODE_PROP_COLORPICKER: PropColorPicker,
361458
NODE_PROP_SLIDER: PropSlider,
362-
NODE_PROP_FILE: PropFilePath
459+
NODE_PROP_FILE: PropFilePath,
460+
NODE_PROP_VECTOR2: PropVector2,
461+
NODE_PROP_VECTOR3: PropVector3,
462+
NODE_PROP_VECTOR4: PropVector4,
463+
NODE_PROP_FLOAT: PropFloat,
464+
NODE_PROP_INT: PropInt,
363465
}
364466

365467

example_auto_nodes/data_node.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,6 @@
33
from .node_base.auto_node import AutoNode
44

55

6-
class VectorValue(AutoNode):
7-
"""
8-
Create a basic vector data
9-
"""
10-
11-
__identifier__ = 'Data'
12-
NODE_NAME = 'Vector'
13-
14-
def __init__(self):
15-
super(VectorValue, self).__init__()
16-
value = [0.0, 0.0, 0.0]
17-
18-
self.add_output('out',list)
19-
self.create_property("out", value)
20-
21-
self.add_float_input('0', 'X', value=value[0])
22-
self.view.widgets['0'].value_changed.connect(lambda: self.updateValue(0))
23-
24-
self.add_float_input('1', 'Y', value=value[1])
25-
self.view.widgets['1'].value_changed.connect(lambda: self.updateValue(1))
26-
27-
self.add_float_input('2', 'Z', value=value[2])
28-
self.view.widgets['2'].value_changed.connect(lambda: self.updateValue(2))
29-
30-
self.defaultValue = value
31-
32-
def updateValue(self, index):
33-
self.get_property("out")[index] = self.get_property(str(index))
34-
self.cook()
35-
36-
376
class VectorSplit(AutoNode):
387
"""
398
Splict a vector to x,y,z
@@ -107,7 +76,6 @@ def __init__(self):
10776
items.append("eval string")
10877
items.append("all to list")
10978
self.add_combo_menu('method', 'Method', items=items)
110-
self.view.widgets['method'].value_changed.connect(self.cook)
11179

11280
def run(self):
11381
method = self.get_property("method")

0 commit comments

Comments
 (0)