205 lines
6.1 KiB
Python
205 lines
6.1 KiB
Python
import logging
|
|
_log = logging.getLogger(__name__)
|
|
|
|
import re
|
|
from PyQt5.QtCore import Qt, pyqtSignal
|
|
from PyQt5.QtWidgets import QLineEdit, QTextEdit, QGridLayout, QVBoxLayout, QWidget, QDialog, QDialogButtonBox, QPushButton
|
|
from PyQt5.QtWidgets import QDoubleSpinBox, QSpinBox, QCheckBox, QLabel
|
|
|
|
def Spinner(value, min=None, max=None, decimals=None, single_step=None, prefix=None, suffix=None):
|
|
if type(value) is float:
|
|
s = QDoubleSpinBox()
|
|
else:
|
|
s = QSpinBox()
|
|
|
|
if min is not None:
|
|
s.setMinimum(min)
|
|
if max is not None:
|
|
s.setMaximum(max)
|
|
try:
|
|
if decimals is not None:
|
|
s.setDecimals(decimals)
|
|
except:
|
|
pass
|
|
if single_step is not None:
|
|
s.setSingleStep(single_step)
|
|
if prefix is not None:
|
|
s.setPrefix(prefix)
|
|
if suffix is not None:
|
|
s.setSuffix(suffix)
|
|
return s
|
|
|
|
def Checkbox(value: bool, label: str):
|
|
box = QCheckBox(label)
|
|
box.setChecked(value)
|
|
return box
|
|
|
|
class MagicLabel(QLabel):
|
|
entered = pyqtSignal(str)
|
|
left = pyqtSignal()
|
|
|
|
def __init__(self, label, help_str, help_buddy=None):
|
|
super(MagicLabel, self).__init__(label)
|
|
self._help_buddy = help_buddy
|
|
self._help_str = help_str
|
|
|
|
def enterEvent(self, event):
|
|
print(self._help_str)
|
|
if self._help_buddy:
|
|
print(f"yay!: {self._help_str}")
|
|
else:
|
|
super().enterEvent(event)
|
|
|
|
def leaveEvent(self, event):
|
|
super().leaveEvent(event)
|
|
|
|
|
|
class GenericDialog(QDialog):
|
|
def __init__(self, parent=None, settings=None, title=None, message=None, inputs={}, use_buttons=True):
|
|
super(GenericDialog, self).__init__()
|
|
|
|
self.settings = settings
|
|
|
|
# self.setModal(True)
|
|
self.setAccessibleName("genericDialog")
|
|
self.setLayout(QVBoxLayout())
|
|
|
|
|
|
bbox = QDialogButtonBox()
|
|
doneButton = QPushButton("Done")
|
|
doneButton.clicked.connect(self.accept)
|
|
bbox.addButton(doneButton, QDialogButtonBox.AcceptRole)
|
|
|
|
if use_buttons:
|
|
undoButton = QPushButton("Undo")
|
|
undoButton.clicked.connect(self.undo_all)
|
|
|
|
discardButton = QPushButton("Discard")
|
|
discardButton.clicked.connect(self.discard)
|
|
|
|
bbox.addButton(undoButton, QDialogButtonBox.ActionRole)
|
|
bbox.addButton(discardButton, QDialogButtonBox.RejectRole)
|
|
|
|
lb = QLabel(title)
|
|
lb.setAccessibleName("genericDialogTitle")
|
|
lb.setAlignment(Qt.AlignHCenter)
|
|
self.layout().addWidget(lb)
|
|
|
|
gbox = QWidget()
|
|
self.layout().addWidget(gbox)
|
|
gbox.setLayout(QVBoxLayout())
|
|
mlabel = QLabel(message)
|
|
mlabel.setAccessibleName("genericDialogMessage")
|
|
|
|
gbox.layout().addWidget(mlabel)
|
|
self.setWindowTitle(title)
|
|
|
|
self.contents = QWidget()
|
|
self.contents.setAccessibleName("genericDialogContents")
|
|
self.layout().addWidget(self.contents)
|
|
self.layout().addStretch()
|
|
self.layout().addWidget(bbox)
|
|
if not inputs:
|
|
inputs = {'test': ('Text test', 'initial', QLineEdit()),
|
|
'float': ('Text test 2', 3.14, QDoubleSpinBox(), 5.0),
|
|
'integer': ('Text test 2', 42, QSpinBox()),
|
|
}
|
|
|
|
self.contents.setLayout(QGridLayout())
|
|
layout = self.contents.layout()
|
|
layout.setColumnStretch(1, 2)
|
|
self.results = {}
|
|
self._undo = {}
|
|
for row, config in enumerate(inputs.items()):
|
|
key, config = config
|
|
config = list(config)
|
|
if len(config) == 3:
|
|
config.extend([""])
|
|
label, value, widget, help_str = config
|
|
labwig = MagicLabel(label, help_str)
|
|
layout.addWidget(labwig, row, 0)
|
|
layout.addWidget(widget, row, 1)
|
|
|
|
if hasattr(widget, 'setChecked'):
|
|
widget.setChecked(value)
|
|
widget.stateChanged.connect(lambda v, k=key, w=widget.isChecked: self.update_results(k, w))
|
|
|
|
elif hasattr(widget, 'setValue'):
|
|
widget.setValue(value)
|
|
widget.valueChanged.connect(lambda v, k=key, w=widget.value: self.update_results(k, w))
|
|
|
|
elif hasattr(widget, 'setPlainText'):
|
|
widget.setPlainText(value)
|
|
widget.textChanged.connect(lambda k=key, w=widget.toPlainText: self.update_results(k, w))
|
|
|
|
elif hasattr(widget, 'setText'):
|
|
widget.setText(value)
|
|
widget.editingFinished.connect(lambda k=key, w=widget.text: self.update_results(k, w))
|
|
|
|
self.results[key] = value
|
|
self._undo[key] = (widget, value)
|
|
|
|
def undo_all(self):
|
|
for k, uinfo in self._undo.items():
|
|
widget, value = uinfo
|
|
if hasattr(widget, 'setChecked'):
|
|
widget.setChecked(value)
|
|
|
|
elif hasattr(widget, 'setValue'):
|
|
widget.setValue(value)
|
|
|
|
elif hasattr(widget, 'setPlainText'):
|
|
widget.setPlainText(value)
|
|
|
|
elif hasattr(widget, 'setText'):
|
|
widget.setText(value)
|
|
|
|
def discard(self):
|
|
self.undo_all()
|
|
self.reject()
|
|
|
|
def set_value(self, widget, url):
|
|
m = re.match("^(.*?)://(.*)", url, re.MULTILINE|re.DOTALL)
|
|
method, value = m.groups()
|
|
if method == "setValue":
|
|
widget.setValue(float(value))
|
|
elif method == "setText":
|
|
widget.setText(value)
|
|
else:
|
|
widget.setPlainText(value)
|
|
if self.settings is not None:
|
|
self.settings.setValue(k, value)
|
|
|
|
def update_results(self, key, get_value):
|
|
value = get_value()
|
|
_log.debug(f"settigns {key} => {value}")
|
|
self.results[key] = value
|
|
if self.settings is not None:
|
|
self.settings.setValue(k, value)
|
|
|
|
def keyPressEvent(self, key_event):
|
|
if key_event != Qt.Key_Escape:
|
|
super().keyPressEvent(key_event)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
from PyQt5.QtWidgets import QApplication
|
|
|
|
app = QApplication(sys.argv)
|
|
title = 'A Lovely Title'
|
|
message = 'thisn sohudl explain what do tod ow with this dialog and in fact we should make sure that it will be wrapping aorufnnfb'
|
|
main = GenericDialog(title=title, message=message, inputs={
|
|
'bananas': ('Number of Bananas', 2, QSpinBox(), 10),
|
|
'apples': ('Number of Apples', 5.5, QDoubleSpinBox(), 23),
|
|
'really': ('Indeed?', True, Checkbox(True, "Contr")),
|
|
'words': ('Words', 'words go here', QLineEdit(), "a few words"),
|
|
'texts': ('Words', 'big words go here', QTextEdit(), """quite a drama\n to write here, really something awfull long"""),
|
|
})
|
|
if main.exec():
|
|
print(main.results)
|
|
for k, v in main.results.items():
|
|
print('{} {} = {}'.format(k, type(v), v))
|
|
sys.exit(app.exec_())
|
|
|