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 QGridLayout, QMenu, QListWidget, QPushButton
|
||||
|
||||
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))
|
||||
|
||||
from PyQt6.QtWidgets import QGridLayout, QMenu, QListWidget, QPushButton, QFormLayout, QDialog, QDialogButtonBox
|
||||
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
class MetadataInput2(QWidget):
|
||||
class MetadataInput(QWidget):
|
||||
def __init__(self, elements: list[tuple[str, str]]=None):
|
||||
super().__init__()
|
||||
self.layout = QGridLayout()
|
||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.layout.setSpacing(0)
|
||||
self.l_vbox = QVBoxLayout()
|
||||
self.l_vbox.addWidget(QLabel("Measurement Metadata"))
|
||||
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:
|
||||
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=""):
|
||||
row = self.layout.rowCount()
|
||||
label_widget = QLabel(name)
|
||||
self.layout.addWidget(label_widget, row, 0)
|
||||
def layout_changed(self):
|
||||
# align at the top with space at the bottom
|
||||
for r in range(self.l_grid.rowCount()):
|
||||
self.l_grid.setRowStretch(r, 0)
|
||||
self.l_grid.setRowStretch(self.l_grid.rowCount(), 1)
|
||||
|
||||
if isinstance(init_val, str):
|
||||
input_widget = QLineEdit(init_val)
|
||||
elif isinstance(init_val, int):
|
||||
input_widget = QSpinBox()
|
||||
input_widget.setValue(init_val)
|
||||
elif isinstance(init_val, float):
|
||||
input_widget = QDoubleSpinBox()
|
||||
input_widget.setValue(init_val)
|
||||
else:
|
||||
input_widget = QLineEdit(str(init_val))
|
||||
def add_element_dialog(self):
|
||||
"""
|
||||
Prompt for a new key-value pair using a Dialog having a form
|
||||
"""
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("Add new field")
|
||||
dialog.layout = QFormLayout()
|
||||
dialog.key_input = QLineEdit()
|
||||
dialog.value_input = QLineEdit()
|
||||
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
|
||||
remove_button = QPushButton("X")
|
||||
remove_button.setFixedSize(20, 20)
|
||||
remove_button.clicked.connect(lambda: self.remove_element(label_widget))
|
||||
self.layout.addWidget(remove_button, row, 2)
|
||||
btn_remove = QPushButton("X")
|
||||
btn_remove.setFixedSize(20, 20)
|
||||
btn_remove.clicked.connect(lambda: self.remove_element(key))
|
||||
self.l_grid.addWidget(btn_remove, row, 2)
|
||||
|
||||
def remove_element(self, label_widget):
|
||||
# get position of label widget
|
||||
# TODO Fix
|
||||
row = self.layout.indexOf(label_widget)
|
||||
# remove all widgets in row
|
||||
for i in range(self.layout.columnCount()):
|
||||
widget = self.layout.itemAtPosition(row, i).widget()
|
||||
print(widget)
|
||||
self.layout.removeWidget(widget)
|
||||
self.ws_elements[key] = (w_label, w_input, btn_remove)
|
||||
self.layout_changed()
|
||||
|
||||
def remove_element(self, name):
|
||||
if name not in self.ws_elements:
|
||||
raise RuntimeError(f"Can not remove field '{name}', it does not exist")
|
||||
for w in self.ws_elements[name]:
|
||||
self.l_grid.removeWidget(w)
|
||||
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):
|
||||
"""
|
||||
@ -78,8 +134,8 @@ class MetadataInput2(QWidget):
|
||||
Dictionary of all key-values pairs
|
||||
"""
|
||||
d = {}
|
||||
for row in range(self.layout.rowCount()):
|
||||
key = self.layout.itemAtPosition(row, 0).widget().text()
|
||||
value = self.layout.itemAtPosition(row, 1).widget().text()
|
||||
for name, (w_label, w_input, _) in self.ws_elements.items():
|
||||
key = w_label.text()
|
||||
value = w_input.text()
|
||||
d[key] = value
|
||||
return d
|
Loading…
x
Reference in New Issue
Block a user