1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
#****************************************************************************
# optiondlg.py, provides classes for option setting dialogs
#
# Copyright (C) 2014, Douglas W. Bell
#
# This is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License, either Version 2 or any later
# version. This program is distributed in the hope that it will be useful,
# but WITTHOUT ANY WARRANTY. See the included LICENSE file for details.
#*****************************************************************************
import sys
from PyQt4 import QtCore, QtGui
class OptionDlg(QtGui.QDialog):
"""Works with Option class to provide a dialog for pref/options.
"""
def __init__(self, option, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint |
QtCore.Qt.WindowSystemMenuHint)
self.option = option
topLayout = QtGui.QVBoxLayout(self)
self.setLayout(topLayout)
self.columnLayout = QtGui.QHBoxLayout()
topLayout.addLayout(self.columnLayout)
self.gridLayout = QtGui.QGridLayout()
self.columnLayout.addLayout(self.gridLayout)
self.oldLayout = self.gridLayout
ctrlLayout = QtGui.QHBoxLayout()
topLayout.addLayout(ctrlLayout)
ctrlLayout.addStretch(0)
okButton = QtGui.QPushButton(_('&OK'), self)
ctrlLayout.addWidget(okButton)
okButton.clicked.connect(self.accept)
cancelButton = QtGui.QPushButton(_('&Cancel'), self)
ctrlLayout.addWidget(cancelButton)
cancelButton.clicked.connect(self.reject)
self.setWindowTitle(_('Preferences'))
self.itemList = []
self.curGroup = None
def addItem(self, dlgItem, widget, label=None):
"""Add a control with optional label, called by OptionDlgItem.
"""
row = self.gridLayout.rowCount()
if label:
self.gridLayout.addWidget(label, row, 0)
self.gridLayout.addWidget(widget, row, 1)
else:
self.gridLayout.addWidget(widget, row, 0, 1, 2)
self.itemList.append(dlgItem)
def startGroupBox(self, title, intSpace=5):
"""Use a group box for next added items.
"""
self.curGroup = QtGui.QGroupBox(title, self)
row = self.oldLayout.rowCount()
self.oldLayout.addWidget(self.curGroup, row, 0, 1, 2)
self.gridLayout = QtGui.QGridLayout(self.curGroup)
self.gridLayout.setVerticalSpacing(intSpace)
def endGroupBox(self):
"""Cancel group box for next added items.
"""
self.gridLayout = self.oldLayout
self.curGroup = None
def startNewColumn(self):
"""Cancel any group box and start a second column.
"""
self.curGroup = None
row = self.oldLayout.rowCount()
self.gridLayout = QtGui.QGridLayout()
self.columnLayout.addLayout(self.gridLayout)
self.oldLayout = self.gridLayout
def parentGroup(self):
"""Return parent for new widgets.
"""
if self.curGroup:
return self.curGroup
return self
def accept(self):
"""Called by dialog when OK button pressed.
"""
for item in self.itemList:
item.updateData()
QtGui.QDialog.accept(self)
class OptionDlgItem:
"""Base class for items to add to dialog.
"""
def __init__(self, dlg, key, writeChg):
self.dlg = dlg
self.key = key
self.writeChg = writeChg
self.control = None
def updateData(self):
"""Dummy update function.
"""
pass
class OptionDlgBool(OptionDlgItem):
"""Holds widget for bool checkbox.
"""
def __init__(self, dlg, key, menuText, writeChg=True):
OptionDlgItem.__init__(self, dlg, key, writeChg)
self.control = QtGui.QCheckBox(menuText, dlg.parentGroup())
self.control.setChecked(dlg.option.boolData(key))
dlg.addItem(self, self.control)
def updateData(self):
"""Update Option class based on checkbox status.
"""
if self.control.isChecked() != self.dlg.option.boolData(self.key):
if self.control.isChecked():
self.dlg.option.changeData(self.key, 'yes', self.writeChg)
else:
self.dlg.option.changeData(self.key, 'no', self.writeChg)
class OptionDlgInt(OptionDlgItem):
"""Holds widget for int spinbox.
"""
def __init__(self, dlg, key, menuText, min, max, writeChg=True, step=1,
wrap=False, suffix=''):
OptionDlgItem.__init__(self, dlg, key, writeChg)
label = QtGui.QLabel(menuText, dlg.parentGroup())
self.control = QtGui.QSpinBox(dlg.parentGroup())
self.control.setMinimum(min)
self.control.setMaximum(max)
self.control.setSingleStep(step)
self.control.setWrapping(wrap)
self.control.setSuffix(suffix)
self.control.setValue(dlg.option.intData(key, min, max))
dlg.addItem(self, self.control, label)
def updateData(self):
"""Update Option class based on spinbox status.
"""
if self.control.value() != int(self.dlg.option.numData(self.key)):
self.dlg.option.changeData(self.key, repr(self.control.value()),
self.writeChg)
class OptionDlgDbl(OptionDlgItem):
"""Holds widget for double line edit.
"""
def __init__(self, dlg, key, menuText, min, max, writeChg=True):
OptionDlgItem.__init__(self, dlg, key, writeChg)
label = QtGui.QLabel(menuText, dlg.parentGroup())
self.control = QtGui.QLineEdit(repr(dlg.option.numData(key, min, max)),
dlg.parentGroup())
valid = QtGui.QDoubleValidator(min, max, 6, self.control)
self.control.setValidator(valid)
dlg.addItem(self, self.control, label)
def updateData(self):
"""Update Option class based on edit status.
"""
text = self.control.text()
unusedPos = 0
if self.control.validator().validate(text, unusedPos)[0] != \
QtGui.QValidator.Acceptable:
return
num = float(text)
if num != self.dlg.option.numData(self.key):
self.dlg.option.changeData(self.key, repr(num), self.writeChg)
class OptionDlgStr(OptionDlgItem):
"""Holds widget for string line edit.
"""
def __init__(self, dlg, key, menuText, writeChg=True):
OptionDlgItem.__init__(self, dlg, key, writeChg)
label = QtGui.QLabel(menuText, dlg.parentGroup())
self.control = QtGui.QLineEdit(dlg.option.strData(key, True),
dlg.parentGroup())
dlg.addItem(self, self.control, label)
def updateData(self):
"""Update Option class based on edit status.
"""
newStr = self.control.text()
if newStr != self.dlg.option.strData(self.key, True):
self.dlg.option.changeData(self.key, newStr, self.writeChg)
class OptionDlgRadio(OptionDlgItem):
"""Holds widget for exclusive radio button group.
"""
def __init__(self, dlg, key, headText, textList, writeChg=True):
# textList is list of tuples: optionText, labelText
OptionDlgItem.__init__(self, dlg, key, writeChg)
self.optionList = [x[0] for x in textList]
buttonBox = QtGui.QGroupBox(headText, dlg.parentGroup())
self.control = QtGui.QButtonGroup(buttonBox)
layout = QtGui.QVBoxLayout(buttonBox)
buttonBox.setLayout(layout)
optionSetting = dlg.option.strData(key)
id = 0
for optionText, labelText in textList:
button = QtGui.QRadioButton(labelText, buttonBox)
layout.addWidget(button)
self.control.addButton(button, id)
id += 1
if optionText == optionSetting:
button.setChecked(True)
dlg.addItem(self, buttonBox)
def updateData(self):
"""Update Option class based on button status.
"""
data = self.optionList[self.control.checkedId()]
if data != self.dlg.option.strData(self.key):
self.dlg.option.changeData(self.key, data, self.writeChg)
class OptionDlgPush(OptionDlgItem):
"""Holds widget for extra misc. push button.
"""
def __init__(self, dlg, text, cmd):
OptionDlgItem.__init__(self, dlg, '', 0)
self.control = QtGui.QPushButton(text, dlg.parentGroup())
self.control.clicked.connect(cmd)
dlg.addItem(self, self.control)
|