Fix and make it a tiny bit prettier
This commit is contained in:
parent
98f3475d97
commit
e85b5bc0d4
@ -1,23 +1,5 @@
|
|||||||
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QSpacerItem, QSpinBox, QDoubleSpinBox
|
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QLineEdit, QSpacerItem, QSpinBox, QDoubleSpinBox
|
||||||
from PyQt6.QtWidgets import QGridLayout, QMenu, QListWidget, QPushButton
|
from PyQt6.QtWidgets import QGridLayout, QMenu, QListWidget, QPushButton, QFormLayout, QDialog, QDialogButtonBox
|
||||||
|
|
||||||
class MetadataInput(QWidget):
|
|
||||||
def __init__(self, elements: list[tuple[str, str]]=None):
|
|
||||||
super().__init__()
|
|
||||||
self.layout = QVBoxLayout()
|
|
||||||
self.elements = []
|
|
||||||
if elements is not None:
|
|
||||||
for (n, v) in elements:
|
|
||||||
self.addElement(n, v)
|
|
||||||
self.layout.addStretch()
|
|
||||||
self.setLayout(self.layout)
|
|
||||||
|
|
||||||
def addElement(self, name, init_val=""):
|
|
||||||
self.elements.append((name, init_val))
|
|
||||||
self.layout.addWidget(QLabel(name))
|
|
||||||
self.layout.addWidget(QLineEdit(init_val))
|
|
||||||
self.layout.addItem(QSpacerItem(0, 1))
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
QWidget class that contains a variable amount of key - input pairs.
|
QWidget class that contains a variable amount of key - input pairs.
|
||||||
@ -25,51 +7,125 @@ One pair per line in a dense layout
|
|||||||
pairs. The value may be text - line edit, float - qdoublespinbox and int - qspinbox.
|
pairs. The value may be text - line edit, float - qdoublespinbox and int - qspinbox.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class MetadataInput2(QWidget):
|
class MetadataInput(QWidget):
|
||||||
def __init__(self, elements: list[tuple[str, str]]=None):
|
def __init__(self, elements: list[tuple[str, str]]=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.layout = QGridLayout()
|
self.l_vbox = QVBoxLayout()
|
||||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
self.l_vbox.addWidget(QLabel("Measurement Metadata"))
|
||||||
self.layout.setSpacing(0)
|
self.l_grid = QGridLayout()
|
||||||
|
self.l_grid.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.l_grid.setSpacing(0)
|
||||||
|
# first row: key value <new element button>
|
||||||
|
self.l_grid.addWidget(QLabel("Key"), 0, 0)
|
||||||
|
self.l_grid.addWidget(QLabel("Value"), 0, 1)
|
||||||
|
self.btn_new_element = QPushButton("+")
|
||||||
|
self.btn_new_element.setFixedSize(20, 20)
|
||||||
|
self.btn_new_element.clicked.connect(self.add_element_dialog)
|
||||||
|
self.l_grid.addWidget(self.btn_new_element, 0, 2)
|
||||||
|
|
||||||
|
# key-value widgets
|
||||||
|
self.ws_elements = {}
|
||||||
for (n, v) in elements:
|
for (n, v) in elements:
|
||||||
self.add_element(n, v)
|
self.add_element(n, v)
|
||||||
self.setLayout(self.layout)
|
self.l_grid.setContentsMargins(4, 4, 4, 4)
|
||||||
|
self.l_grid.setSpacing(4)
|
||||||
|
self.l_vbox.addLayout(self.l_grid)
|
||||||
|
self.setLayout(self.l_vbox)
|
||||||
|
|
||||||
def add_element(self, name, init_val=""):
|
def layout_changed(self):
|
||||||
row = self.layout.rowCount()
|
# align at the top with space at the bottom
|
||||||
label_widget = QLabel(name)
|
for r in range(self.l_grid.rowCount()):
|
||||||
self.layout.addWidget(label_widget, row, 0)
|
self.l_grid.setRowStretch(r, 0)
|
||||||
|
self.l_grid.setRowStretch(self.l_grid.rowCount(), 1)
|
||||||
|
|
||||||
if isinstance(init_val, str):
|
def add_element_dialog(self):
|
||||||
input_widget = QLineEdit(init_val)
|
"""
|
||||||
elif isinstance(init_val, int):
|
Prompt for a new key-value pair using a Dialog having a form
|
||||||
input_widget = QSpinBox()
|
"""
|
||||||
input_widget.setValue(init_val)
|
dialog = QDialog(self)
|
||||||
elif isinstance(init_val, float):
|
dialog.setWindowTitle("Add new field")
|
||||||
input_widget = QDoubleSpinBox()
|
dialog.layout = QFormLayout()
|
||||||
input_widget.setValue(init_val)
|
dialog.key_input = QLineEdit()
|
||||||
else:
|
dialog.value_input = QLineEdit()
|
||||||
input_widget = QLineEdit(str(init_val))
|
dialog.layout.addRow("Key", dialog.key_input)
|
||||||
|
dialog.layout.addRow("Value", dialog.value_input)
|
||||||
|
|
||||||
self.layout.addWidget(input_widget, row, 1)
|
# ok and cancel
|
||||||
|
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
||||||
|
buttons.accepted.connect(dialog.accept)
|
||||||
|
buttons.rejected.connect(dialog.reject)
|
||||||
|
dialog.layout.addRow(buttons)
|
||||||
|
dialog.setLayout(dialog.layout)
|
||||||
|
|
||||||
|
ret = dialog.exec()
|
||||||
|
if ret == QDialog.DialogCode.Accepted:
|
||||||
|
self.add_element(dialog.key_input.text(), dialog.value_input.text())
|
||||||
|
|
||||||
|
def add_element(self, key, init_val=""):
|
||||||
|
if key in self.ws_elements:
|
||||||
|
raise RuntimeError(f"Can not add field '{key}', it already exists")
|
||||||
|
if key == "":
|
||||||
|
raise RuntimeError(f"Can not add field with empty key")
|
||||||
|
row = self.l_grid.rowCount()
|
||||||
|
w_label = QLabel(key)
|
||||||
|
self.l_grid.addWidget(w_label, row, 0)
|
||||||
|
|
||||||
|
w_input= QLineEdit(str(init_val))
|
||||||
|
|
||||||
|
self.l_grid.addWidget(w_input, row, 1)
|
||||||
|
|
||||||
# Add a small button with an X from the theme
|
# Add a small button with an X from the theme
|
||||||
remove_button = QPushButton("X")
|
btn_remove = QPushButton("X")
|
||||||
remove_button.setFixedSize(20, 20)
|
btn_remove.setFixedSize(20, 20)
|
||||||
remove_button.clicked.connect(lambda: self.remove_element(label_widget))
|
btn_remove.clicked.connect(lambda: self.remove_element(key))
|
||||||
self.layout.addWidget(remove_button, row, 2)
|
self.l_grid.addWidget(btn_remove, row, 2)
|
||||||
|
|
||||||
def remove_element(self, label_widget):
|
self.ws_elements[key] = (w_label, w_input, btn_remove)
|
||||||
# get position of label widget
|
self.layout_changed()
|
||||||
# TODO Fix
|
|
||||||
row = self.layout.indexOf(label_widget)
|
def remove_element(self, name):
|
||||||
# remove all widgets in row
|
if name not in self.ws_elements:
|
||||||
for i in range(self.layout.columnCount()):
|
raise RuntimeError(f"Can not remove field '{name}', it does not exist")
|
||||||
widget = self.layout.itemAtPosition(row, i).widget()
|
for w in self.ws_elements[name]:
|
||||||
print(widget)
|
self.l_grid.removeWidget(w)
|
||||||
self.layout.removeWidget(widget)
|
del self.ws_elements[name]
|
||||||
|
self.layout_changed()
|
||||||
|
|
||||||
|
|
||||||
|
def set_from_dict(self, d: dict[str, str]):
|
||||||
|
"""
|
||||||
|
Set the widgets from the dictionary
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
d
|
||||||
|
Dictionary of key-value pairs
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
# first remove widgets not in new dict
|
||||||
|
for key in self.ws_elements.keys():
|
||||||
|
if key not in d:
|
||||||
|
self.remove_element(key)
|
||||||
|
self.update_from_dict(d)
|
||||||
|
|
||||||
|
def update_from_dict(self, d: dict[str, str]):
|
||||||
|
"""
|
||||||
|
Update widgets from the dictionary.
|
||||||
|
New values will be added, no values will be removed
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
d
|
||||||
|
Dictionary of key-value pairs
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
for key, value in d.items():
|
||||||
|
if key not in self.ws_elements:
|
||||||
|
self.add_element(key, value)
|
||||||
|
else:
|
||||||
|
self.ws_elements[key][1].setText(value)
|
||||||
|
|
||||||
def get_dict(self):
|
def get_dict(self):
|
||||||
"""
|
"""
|
||||||
@ -78,8 +134,8 @@ class MetadataInput2(QWidget):
|
|||||||
Dictionary of all key-values pairs
|
Dictionary of all key-values pairs
|
||||||
"""
|
"""
|
||||||
d = {}
|
d = {}
|
||||||
for row in range(self.layout.rowCount()):
|
for name, (w_label, w_input, _) in self.ws_elements.items():
|
||||||
key = self.layout.itemAtPosition(row, 0).widget().text()
|
key = w_label.text()
|
||||||
value = self.layout.itemAtPosition(row, 1).widget().text()
|
value = w_input.text()
|
||||||
d[key] = value
|
d[key] = value
|
||||||
return d
|
return d
|
Loading…
x
Reference in New Issue
Block a user