Creates a simple dialog box based on a dictionary with various keys like (check, list, and linedit)
Last active
January 17, 2017 16:15
-
-
Save kmader/ebf8dc2db5fd06bc064319dd818c7c41 to your computer and use it in GitHub Desktop.
DictDialog in pyqt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# keep the imports explicit so we can reuse this somewhere else | |
from qt import QDialog, QVBoxLayout, QHBoxLayout | |
from qt import QCheckBox, QListWidget, QLineEdit, QDateTimeEdit, QDateTime | |
from qt import QDialogButtonBox, QDialogButtonBox | |
from qt import Qt | |
class DictDialog(QDialog): | |
""" | |
Create an input dialog from a dictionary containing the items and default values to be shown. The primary tags are | |
check -> Checkbox | |
list -> ListWidget | |
lineedit -> LineEdit / Textbox | |
""" | |
def __init__(self, raw_obj_dict, parent=None): | |
# type: (DictDialog, Dict[str, Any], qt.QWidget) -> None | |
super(DictDialog, self).__init__(parent) | |
layout = QVBoxLayout(self) | |
self.widget_dict = OrderedDict() # type: Dict[str, qt.QWidget] | |
obj_dict = raw_obj_dict.copy() | |
layout.addWidget(make_qlabel(obj_dict.pop('msg', ''))) | |
for key, def_val in obj_dict.items(): | |
if type(def_val) is tuple: | |
def_val, tt_msg = def_val | |
else: | |
tt_msg = '' | |
if key.lower().find('check') >= 0: | |
clean_key = key[:key.lower().find('check')] | |
c_box = QCheckBox(clean_key.replace('_', ' ')) | |
c_box.setChecked(def_val) | |
c_box.setToolTip(tt_msg) | |
layout.addWidget(c_box) | |
self.widget_dict[clean_key] = lambda: 'T' if c_box.checked else 'F' | |
elif key.lower().find('list') >= 0: | |
clean_key = key[:key.lower().find('list')] | |
c_list = QListWidget() | |
c_list.addItems(def_val) | |
c_list.setToolTip(tt_msg) | |
c_list.setCurrentRow(0) | |
t_layout = QVBoxLayout() | |
t_layout.addWidget(make_qlabel(clean_key.replace('_', ' '))) | |
t_layout.addWidget(c_list) | |
layout.addLayout(t_layout) | |
self.widget_dict[clean_key] = lambda: c_list.currentItem().text().replace(' ','_') | |
elif key.lower().find('lineedit') >= 0: | |
clean_key = key[:key.lower().find('lineedit')] | |
t_layout = QHBoxLayout() | |
i_label = make_qlabel(clean_key.replace('_', ' ')) | |
c_line = QLineEdit() | |
c_line.setText(def_val) | |
c_line.setToolTip(tt_msg) | |
t_layout.addWidget(i_label) | |
t_layout.addWidget(c_line) | |
layout.addLayout(t_layout) | |
self.widget_dict[clean_key] = lambda: c_line.text | |
elif key.lower().find('date')>=0: | |
clean_key = key[:key.lower().find('date')] | |
t_layout = QHBoxLayout() | |
i_label = make_qlabel(clean_key.replace('_', ' ')) | |
t_layout.addWidget(i_label) | |
n_date = QDateTimeEdit() | |
n_date.setCalendarPopup(True) | |
n_date.setDateTime(QDateTime.currentDateTime()) | |
n_date.setToolTip(tt_msg) | |
t_layout.addWidget(n_date) | |
layout.addLayout(t_layout) | |
self.widget_dict[clean_key] = lambda: n_date.dateTime.toString() | |
else: | |
i_label = make_qlabel('{} ({})'.format(key, def_val)) | |
t_layout = QHBoxLayout() | |
t_layout.addWidget(i_label) | |
layout.addLayout(t_layout) | |
logging.warning("Type not supported yet {}".format(key)) | |
# OK and Cancel buttons | |
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) | |
buttons.accepted.connect(self.accept) | |
buttons.rejected.connect(self.reject) | |
layout.addWidget(buttons) | |
def harvest(self): | |
""" | |
get the value from all of the fields | |
:return: | |
""" | |
return {key: val_fcn() for key, val_fcn in self.widget_dict.items()} | |
@staticmethod | |
def getDict(obj_dict, parent=None): | |
""" | |
creates a dialog with the components and returns a dictionary of the values | |
:param parent: | |
:return: | |
""" | |
dialog = DictDialog(obj_dict, parent) | |
result = dialog.exec_() | |
return (dialog.harvest(), result == QDialog.Accepted) | |
@staticmethod | |
def getString(obj_dict, parent=None, join_chr = ',', key_val_chr = '='): | |
""" | |
Get a string from a dialog instead of the entire dictionary | |
:param obj_dict: | |
:param parent: | |
:return: | |
""" | |
all_dict, ok = DictDialog.getDict(obj_dict, parent) | |
text = join_chr.join(['{}{}{}'.format(key, key_val_chr, val) for key, val in all_dict.items() if val != '']) | |
return text, ok |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment