164 lines
6.8 KiB
Python
164 lines
6.8 KiB
Python
import collections
|
|
from PySide6 import QtCore, QtWidgets
|
|
from QT.Main_Window import Attr_Dict
|
|
|
|
class Input_Dialog (QtWidgets.QDialog) :
|
|
|
|
def __init__ (self, title, ** spec) :
|
|
super ().__init__ (spec.pop ("parent", None))
|
|
self.setWindowTitle (title)
|
|
self.layout = L = QtWidgets.QFormLayout (self)
|
|
self.widgets = {}
|
|
self.min_width = spec.pop ("_MIN_WIDTH", 200)
|
|
self.field_spec = spec
|
|
self.dependencies = collections.defaultdict (list)
|
|
for name, fspec in spec.items () :
|
|
type = fspec.get ("type")
|
|
default = fspec.get ("default")
|
|
if type is None and default is not None :
|
|
type = default.__class__.__name__
|
|
getattr (self, "_add_%s" % type, self._add_str) \
|
|
(L, name, fspec, default, type)
|
|
for attr, format in fspec.get ("auto", {}).items () :
|
|
self.dependencies [attr].append ((name, format))
|
|
layout = QtWidgets.QHBoxLayout ()
|
|
ok = QtWidgets.QPushButton ("OK")
|
|
ok.clicked.connect (self.store_values)
|
|
cancel = QtWidgets.QPushButton ("Cancel")
|
|
cancel.clicked.connect (self.reject)
|
|
layout.addStretch (10)
|
|
layout.addWidget (ok)
|
|
layout.addWidget (cancel)
|
|
ok.setDefault (True)
|
|
L.addRow (layout)
|
|
self.setMinimumWidth (self.min_width)
|
|
self.result = Attr_Dict ()
|
|
# end def __init__
|
|
|
|
def get_values (self) :
|
|
data = Attr_Dict ()
|
|
errors = {}
|
|
for name, (getter, _) in self.widgets.items () :
|
|
data [name] = value = getter ()
|
|
fspec = self.field_spec [name]
|
|
if not value and fspec.get ("required", False) :
|
|
errors [name] = "Required"
|
|
return data, errors
|
|
# end def store_values
|
|
|
|
def store_values (self) :
|
|
self.result, errors = self.get_values ()
|
|
if not errors :
|
|
self.accept ()
|
|
# end def store_values
|
|
|
|
def _auto_update (self, changed) :
|
|
if changed in self.dependencies :
|
|
values, _ = self.get_values ()
|
|
for attr, format in self.dependencies [changed] :
|
|
if not values.get (attr) :
|
|
self.widgets [attr] [1] (format % values)
|
|
# end def _auto_update
|
|
|
|
def _add_str (self, L, name, fspec, default, type) :
|
|
widget = QtWidgets.QLineEdit ()
|
|
widget.setText (default or "")
|
|
self.widgets [name] = widget.text, widget.setText
|
|
L.addRow (fspec.get ("title", name.capitalize ()), widget)
|
|
widget.editingFinished.connect \
|
|
(lambda : self._auto_update (name))
|
|
# end def _add_str
|
|
|
|
def _add_int (self, L, name, fspec, default, type) :
|
|
widget = QtWidgets.QSpinBox ()
|
|
widget.setRange (-65536, 0x7FFFFFFF)
|
|
widget.setValue (default or 0)
|
|
self.widgets [name] = widget.value, widget.setValue
|
|
L.addRow (fspec.get ("title", name.capitalize ()), widget)
|
|
widget.editingFinished.connect \
|
|
(lambda : self._auto_update (name))
|
|
# end def _add_int
|
|
|
|
def _add_file_dialog (self, cb, L, name, fspec, default) :
|
|
layout = QtWidgets.QHBoxLayout ()
|
|
current = QtWidgets.QLineEdit ()
|
|
current.setText (default or "")
|
|
current.setEnabled (False)
|
|
change = QtWidgets.QPushButton ("...")
|
|
change.setFixedWidth (24)
|
|
change.clicked.connect (lambda : cb (fspec, current))
|
|
layout.addWidget (current)
|
|
layout.addWidget (change)
|
|
layout.setStretch (0, 10)
|
|
self.widgets [name] = current.text, current.setText
|
|
L.addRow (fspec.get ("title", name.capitalize ()), layout)
|
|
self.min_width = max (self.min_width, 600)
|
|
# end def _add_file_dialog
|
|
|
|
def _add_open_filename (self, L, name, fspec, default, type) :
|
|
self._add_file_dialog \
|
|
(self._choose_file_dialog, L, name, fspec, default)
|
|
# end def _add_open_filename
|
|
|
|
def _choose_file_dialog (self, fspec, current) :
|
|
filter = fspec.get ("filter", ())
|
|
filter = ";;".join ("%s (%s)" % (t, e) for (t, e) in filter)
|
|
file_name = QtWidgets.QFileDialog.getOpenFileName \
|
|
( filter = filter
|
|
) [0]
|
|
if file_name :
|
|
current.setText (file_name)
|
|
# end def _choose_file_dialog
|
|
|
|
def _add_save_filename (self, L, name, fspec, default, type) :
|
|
self._add_file_dialog \
|
|
(self._save_file_dialog, L, name, fspec, default)
|
|
# end def _add_open_filename
|
|
|
|
def _save_file_dialog (self, fspec, current) :
|
|
filter = fspec.get ("filter", ())
|
|
filter = ";;".join ("%s (%s)" % (t, e) for (t, e) in filter)
|
|
file_name = QtWidgets.QFileDialog.getSaveFileName \
|
|
( filter = filter
|
|
) [0]
|
|
if file_name :
|
|
current.setText (file_name)
|
|
# end def _save_file_dialog
|
|
|
|
def _add_drop_down (self, L, name, fspec, default, type) :
|
|
widget = QtWidgets.QComboBox ()
|
|
for idx, e in enumerate \
|
|
(sorted (fspec ["choices"], key = lambda e : e ["label"])) :
|
|
widget.addItem (e ["label"], e ["value"])
|
|
if "tooltip" in e :
|
|
widget.setItemData \
|
|
(idx, e ["tooltip"], QtCore.Qt.ToolTipRole)
|
|
self.widgets [name] = widget.currentText, widget.setCurrentText
|
|
L.addRow (fspec.get ("title", name.capitalize ()), widget)
|
|
widget.currentTextChanged.connect \
|
|
(lambda : self._auto_update (name))
|
|
# end def _add_drop_down
|
|
|
|
def run (self) :
|
|
if self.exec () == 1 :
|
|
return self.result
|
|
# end def run
|
|
|
|
# end class Input_Dialog
|
|
|
|
if __name__ == "__main__" :
|
|
app = QtWidgets.QApplication ([])
|
|
r = Input_Dialog \
|
|
( "Test"
|
|
, name = {"default": "", "title" : "Layer Name", "required": True}
|
|
, file_name = {"default": "", "title" : "Filename"
|
|
, "type" : "save_filename"
|
|
, "filter": ( ( "Layer Files", "*.layer")
|
|
, ( "Json Files", "*.json")
|
|
, ( "All Files", "*.*")
|
|
)
|
|
, "auto" : {"name" : "%(name)s/%(name)s.layer"}
|
|
}
|
|
).run ()
|
|
if r is not None :
|
|
print (r) |