Skip to content

Instantly share code, notes, and snippets.

@kmader
Last active January 17, 2017 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kmader/ebf8dc2db5fd06bc064319dd818c7c41 to your computer and use it in GitHub Desktop.
Save kmader/ebf8dc2db5fd06bc064319dd818c7c41 to your computer and use it in GitHub Desktop.
DictDialog in pyqt

Overview

Creates a simple dialog box based on a dictionary with various keys like (check, list, and linedit)

# 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