Skip to content

Commit 2d72cae

Browse files
committed
add new file path properties widget && add file_dialog
1 parent 0b2f721 commit 2d72cae

File tree

8 files changed

+142
-55
lines changed

8 files changed

+142
-55
lines changed

NodeGraphQt/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ def __init__(self):
7474
"""
7575

7676
try:
77-
from Qt import QtWidgets, QtGui, QtCore, QtCompat
77+
from Qt import QtWidgets, QtGui, QtCore, QtCompat, QtOpenGL
7878
except ImportError as ie:
7979
from .vendor.Qt import __version__ as qtpy_ver
80-
from .vendor.Qt import QtWidgets, QtGui, QtCore, QtCompat
80+
from .vendor.Qt import QtWidgets, QtGui, QtCore, QtCompat ,QtOpenGL
8181
print('Cannot import "Qt.py" module falling back on '
8282
'"NodeGraphQt.vendor.Qt ({})"'.format(qtpy_ver))
8383

NodeGraphQt/base/node.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
NODE_PROP_QTEXTEDIT,
88
NODE_PROP_QCOMBO,
99
NODE_PROP_QCHECKBOX,
10-
IN_PORT, OUT_PORT)
10+
IN_PORT, OUT_PORT,
11+
NODE_PROP_FILE)
1112
from NodeGraphQt.errors import PortRegistrationError
1213
from NodeGraphQt.qgraphics.node_backdrop import BackdropNodeItem
1314
from NodeGraphQt.qgraphics.node_base import NodeItem
@@ -511,7 +512,7 @@ def add_combo_menu(self, name, label='', items=None, tab=None):
511512
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
512513
self.view.add_widget(widget)
513514

514-
def add_text_input(self, name, label='', text='', tab=None):
515+
def add_text_input(self, name, label='', text='', tab=None, multi_line=False):
515516
"""
516517
Creates a custom property with the :meth:`NodeObject.create_property`
517518
function and embeds a :class:`PySide2.QtWidgets.QLineEdit` widget
@@ -526,9 +527,14 @@ def add_text_input(self, name, label='', text='', tab=None):
526527
label (str): label to be displayed.
527528
text (str): pre filled text.
528529
tab (str): name of the widget tab to display in.
530+
multi_line (bool): if create multi line property.
529531
"""
532+
if multi_line:
533+
wid_type = NODE_PROP_QTEXTEDIT
534+
else:
535+
wid_type = NODE_PROP_QLINEEDIT
530536
self.create_property(
531-
name, text, widget_type=NODE_PROP_QLINEEDIT, tab=tab)
537+
name, text, widget_type=wid_type, tab=tab)
532538
widget = NodeLineEdit(self.view, name, label, text)
533539
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
534540
self.view.add_widget(widget)
@@ -551,10 +557,9 @@ def add_file_input(self, name, label='', text='', tab=None, ext="*"):
551557
ext (str): file ext
552558
"""
553559
self.create_property(
554-
name, text, widget_type=NODE_PROP_QLINEEDIT, tab=tab)
560+
name, text, widget_type=NODE_PROP_FILE, tab=tab)
555561
widget = NodeFilePath(self.view, name, label, text,ext)
556562
widget.value_changed.connect(lambda k, v: self.set_property(k, v))
557-
widget._node = self
558563
self.view.add_widget(widget)
559564

560565
def add_float_input(self, name, label='', value=0.0, tab=None):

NodeGraphQt/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
NODE_PROP_COLORPICKER = 8
7070
#: Property type represented with a Slider widget in the properties bin.
7171
NODE_PROP_SLIDER = 9
72+
#: Property type represented with a file selector widget in the properties bin.
73+
NODE_PROP_FILE = 10
7274

7375
# === NODE VIEWER ===
7476

@@ -100,4 +102,4 @@
100102
# QGraphicsItem.ItemCoordinateCache
101103
# QGraphicsItem.DeviceCoordinateCache
102104

103-
ITEM_CACHE_MODE = QtWidgets.QGraphicsItem.DeviceCoordinateCache
105+
ITEM_CACHE_MODE = QtWidgets.QGraphicsItem.ItemCoordinateCache

NodeGraphQt/widgets/file_dialog.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from NodeGraphQt import QtWidgets
2+
import os
3+
4+
current_dir = os.path.expanduser('~')
5+
6+
7+
def set_dir(file):
8+
global current_dir
9+
if os.path.isdir(file):
10+
current_dir = file
11+
elif os.path.isfile(file):
12+
current_dir = os.path.split(file)[0]
13+
14+
15+
class file_dialog(object):
16+
17+
@staticmethod
18+
def getSaveFileName(parent=None, title="Save File", file_dir=None, ext_filter="*"):
19+
if not file_dir:
20+
file_dir = current_dir
21+
file_dlg = QtWidgets.QFileDialog.getSaveFileName(
22+
parent, title, file_dir, ext_filter)
23+
file = file_dlg[0] or None
24+
if file:
25+
set_dir(file)
26+
return file_dlg
27+
28+
@staticmethod
29+
def getOpenFileName(parent=None, title="Open File", file_dir=None, ext_filter="*"):
30+
if not file_dir:
31+
file_dir = current_dir
32+
33+
file_dlg = QtWidgets.QFileDialog.getOpenFileName(
34+
parent, title, file_dir, ext_filter)
35+
36+
file = file_dlg[0] or None
37+
if file:
38+
set_dir(file)
39+
40+
return file_dlg
41+
42+

NodeGraphQt/widgets/node_widgets.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from NodeGraphQt.constants import Z_VAL_NODE_WIDGET
55
from NodeGraphQt.widgets.stylesheet import *
6+
from NodeGraphQt.widgets.file_dialog import file_dialog
67

78

89
class _NodeGroupBox(QtWidgets.QGroupBox):
@@ -230,10 +231,10 @@ def __init__(self, parent=None, name='', label='', text=''):
230231
self._ledit.setAlignment(QtCore.Qt.AlignCenter)
231232
self._ledit.editingFinished.connect(self._value_changed)
232233
self._ledit.clearFocus()
233-
self.group = _NodeGroupBox(label)
234-
self.group.add_node_widget(self._ledit)
235-
self.group.setMaximumWidth(120)
236-
self.setWidget(self.group)
234+
group = _NodeGroupBox(label)
235+
group.add_node_widget(self._ledit)
236+
group.setMaximumWidth(120)
237+
self.setWidget(group)
237238
self.text = text
238239

239240
@property
@@ -364,38 +365,35 @@ class NodeFilePath(NodeLineEdit):
364365
:meth:`NodeGraphQt.BaseNode.add_float_input`
365366
"""
366367

367-
def __init__(self, parent=None, name='', label='', text='',ext="*"):
368-
super(NodeLineEdit,self).__init__(parent, name, label)
368+
def __init__(self, parent=None, name='', label='', text='', ext="*"):
369+
super(NodeLineEdit, self).__init__(parent, name, label)
369370
self._ledit = QtWidgets.QLineEdit()
370371
self._ledit.setStyleSheet(STYLE_QLINEEDIT)
371372
self._ledit.setAlignment(QtCore.Qt.AlignCenter)
372373
self._ledit.editingFinished.connect(self._value_changed)
373374
self._ledit.clearFocus()
374375

375-
self._button = QtWidgets.QPushButton()
376-
self._button.setStyleSheet(STYLE_QPUSHBUTTON)
377-
self._button.setIcon(self.get_icon(21))
376+
_button = QtWidgets.QPushButton()
377+
_button.setStyleSheet(STYLE_QPUSHBUTTON)
378+
_button.setIcon(self.get_icon(21))
378379

379380
widget = QtWidgets.QWidget()
380381
hbox = QtWidgets.QHBoxLayout()
381382
hbox.addWidget(self._ledit)
382-
hbox.addWidget(self._button)
383+
hbox.addWidget(_button)
383384
widget.setLayout(hbox)
384385
widget.setStyleSheet(STYLE_QWIDGET)
385386

386-
self.group = _NodeGroupBox(label)
387-
self.group.add_node_widget(widget)
387+
group = _NodeGroupBox(label)
388+
group.add_node_widget(widget)
388389
self.text = text
389390

390-
self._button.clicked.connect(self._on_select_file)
391-
self.setWidget(self.group)
392-
393-
self._node = None
391+
_button.clicked.connect(self._on_select_file)
392+
self.setWidget(group)
394393
self._ext = ext
395394

396395
def _on_select_file(self):
397-
if self._node:
398-
viewer = self._node.graph.viewer()
399-
file_path = viewer.load_dialog(ext=self._ext)
400-
if file_path:
401-
self.value = file_path
396+
file_path = file_dialog.getOpenFileName()
397+
file = file_path[0] or None
398+
if file:
399+
self.value = file

NodeGraphQt/widgets/properties.py

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
NODE_PROP_QCHECKBOX,
1010
NODE_PROP_QSPINBOX,
1111
NODE_PROP_COLORPICKER,
12-
NODE_PROP_SLIDER)
12+
NODE_PROP_SLIDER,
13+
NODE_PROP_FILE)
14+
from NodeGraphQt.widgets.file_dialog import file_dialog
1315

1416

1517
class BaseProperty(QtWidgets.QWidget):
@@ -199,9 +201,10 @@ def get_value(self):
199201
return self.text()
200202

201203
def set_value(self, value):
202-
if value != self.get_value():
203-
self.setText(str(value))
204-
self.value_changed.emit(self.toolTip(), value)
204+
_value = str(value)
205+
if _value != self.get_value():
206+
self.setText(_value)
207+
self.value_changed.emit(self.toolTip(), _value)
205208

206209

207210
class PropTextEdit(QtWidgets.QTextEdit):
@@ -229,9 +232,10 @@ def get_value(self):
229232
return self.toPlainText()
230233

231234
def set_value(self, value):
232-
if value != self.get_value():
233-
self.setPlainText(value)
234-
self.value_changed.emit(self.toolTip(), value)
235+
_value = str(value)
236+
if _value != self.get_value():
237+
self.setPlainText(_value)
238+
self.value_changed.emit(self.toolTip(), _value)
235239

236240

237241
class PropComboBox(QtWidgets.QComboBox):
@@ -303,6 +307,49 @@ def set_value(self, value):
303307
self.setValue(value)
304308

305309

310+
class PropFilePath(QtWidgets.QWidget):
311+
312+
value_changed = QtCore.Signal(str, object)
313+
314+
def __init__(self, parent=None):
315+
super(PropFilePath, self).__init__(parent)
316+
self._ledit = QtWidgets.QLineEdit()
317+
self._ledit.setAlignment(QtCore.Qt.AlignLeft)
318+
self._ledit.editingFinished.connect(self._on_value_change)
319+
self._ledit.clearFocus()
320+
321+
icon = self.style().standardIcon(QtWidgets.QStyle.StandardPixmap(21))
322+
_button = QtWidgets.QPushButton()
323+
_button.setIcon(icon)
324+
325+
hbox = QtWidgets.QHBoxLayout()
326+
hbox.addWidget(self._ledit)
327+
hbox.addWidget(_button)
328+
self.setLayout(hbox)
329+
_button.clicked.connect(self._on_select_file)
330+
331+
self._ledit.setStyleSheet("QLineEdit{border:1px solid}")
332+
_button.setStyleSheet("QPushButton{border:1px solid}")
333+
334+
def _on_select_file(self):
335+
file_path = file_dialog.getOpenFileName(self)
336+
file = file_path[0] or None
337+
if file:
338+
self.set_value(file)
339+
340+
def _on_value_change(self, value):
341+
self.value_changed.emit(self.toolTip(), value)
342+
343+
def get_value(self):
344+
return self._ledit.text()
345+
346+
def set_value(self, value):
347+
_value = str(value)
348+
if _value != self.get_value():
349+
self._ledit.setText(_value)
350+
self._on_value_change(_value)
351+
352+
306353
WIDGET_MAP = {
307354
NODE_PROP_QLABEL: PropLabel,
308355
NODE_PROP_QLINEEDIT: PropLineEdit,
@@ -312,6 +359,7 @@ def set_value(self, value):
312359
NODE_PROP_QSPINBOX: PropSpinBox,
313360
NODE_PROP_COLORPICKER: PropColorPicker,
314361
NODE_PROP_SLIDER: PropSlider,
362+
NODE_PROP_FILE: PropFilePath
315363
}
316364

317365

@@ -463,7 +511,7 @@ def _read_node(self, node):
463511
if tab != 'Node':
464512
self.add_tab(tab)
465513

466-
widget_height = 25
514+
min_widget_height = 25
467515
# populate tab properties.
468516
for tab in sorted(tab_mapping.keys()):
469517
prop_window = self.__tab_windows[tab]
@@ -474,8 +522,7 @@ def _read_node(self, node):
474522

475523
WidClass = WIDGET_MAP.get(wid_type)
476524
widget = WidClass()
477-
if wid_type != NODE_PROP_QTEXTEDIT:
478-
widget.setFixedHeight(widget_height)
525+
widget.setMinimumHeight(min_widget_height)
479526
if prop_name in common_props.keys():
480527
if 'items' in common_props[prop_name].keys():
481528
widget.set_items(common_props[prop_name]['items'])
@@ -497,7 +544,7 @@ def _read_node(self, node):
497544
WidClass = WIDGET_MAP.get(wid_type)
498545

499546
widget = WidClass()
500-
widget.setFixedHeight(widget_height)
547+
widget.setMinimumHeight(min_widget_height)
501548
prop_window.add_widget(prop_name,
502549
widget,
503550
model.get_property(prop_name),

NodeGraphQt/widgets/viewer.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import math
44
import os
55

6-
from NodeGraphQt import QtGui, QtCore, QtWidgets
6+
from NodeGraphQt import QtGui, QtCore, QtWidgets ,QtOpenGL
77
from NodeGraphQt.constants import (IN_PORT, OUT_PORT,
88
PIPE_LAYOUT_CURVED)
99
from NodeGraphQt.qgraphics.node_abstract import AbstractNodeItem
@@ -14,7 +14,7 @@
1414
from NodeGraphQt.widgets.actions import BaseMenu
1515
from NodeGraphQt.widgets.scene import NodeScene
1616
from NodeGraphQt.widgets.tab_search import TabSearchWidget, TabSearchMenuWidget
17-
from Qt import QtOpenGL
17+
from NodeGraphQt.widgets.file_dialog import file_dialog
1818

1919
ZOOM_MIN = -0.95
2020
ZOOM_MAX = 2.0
@@ -57,7 +57,6 @@ def __init__(self, parent=None):
5757
self._update_scene()
5858
self._last_size = self.size()
5959

60-
self.current_dir = os.path.expanduser('~')
6160
self._pipe_layout = PIPE_LAYOUT_CURVED
6261
self._detached_port = None
6362
self._start_port = None
@@ -722,28 +721,21 @@ def message_dialog(self, text, title='Node Graph'):
722721
self, title, text, QtWidgets.QMessageBox.Ok)
723722

724723
def load_dialog(self, current_dir=None, ext=None):
725-
self.current_dir = current_dir or self.current_dir
726724
ext = '*{} '.format(ext) if ext else ''
727725
ext_filter = ';;'.join([
728726
'Node Graph ({}*json)'.format(ext), 'All Files (*)'
729727
])
730-
file_dlg = QtWidgets.QFileDialog.getOpenFileName(
731-
self, 'Open File', self.current_dir, ext_filter)
728+
file_dlg = file_dialog.getOpenFileName(
729+
self, 'Open File', current_dir, ext_filter)
732730
file = file_dlg[0] or None
733-
if file:
734-
if os.path.isdir(file):
735-
self.current_dir = file
736-
elif os.path.isfile(file):
737-
self.current_dir = os.path.split(file)[0]
738731
return file
739732

740733
def save_dialog(self, current_dir=None, ext=None):
741-
current_dir = current_dir or os.path.expanduser('~')
742734
ext_label = '*{} '.format(ext) if ext else ''
743735
ext_type = '.{}'.format(ext) if ext else '.json'
744736
ext_map = {'Node Graph ({}*json)'.format(ext_label): ext_type,
745737
'All Files (*)': ''}
746-
file_dlg = QtWidgets.QFileDialog.getSaveFileName(
738+
file_dlg = file_dialog.getSaveFileName(
747739
self, 'Save Session', current_dir, ';;'.join(ext_map.keys()))
748740
file_path = file_dlg[0]
749741
if not file_path:
@@ -752,7 +744,6 @@ def save_dialog(self, current_dir=None, ext=None):
752744
if ext and not file_path.endswith(ext):
753745
file_path += ext
754746

755-
self.current_dir = os.path.split(file_path)[0]
756747
return file_path
757748

758749
def all_pipes(self):

0 commit comments

Comments
 (0)