patternpythonMinor
Binding a value to a control
Viewed 0 times
controlvaluebinding
Problem
I'm currently writing some code in PyQt4 that takes a value and a control and binds the value to the control. Once the user saves the form it will unbind all the values and save it back to a custom object (in this case QgsFeature).
At the moment, I have the bind and unbind code which uses
```
def bindValueToControl(self, control, value):
"""
Binds a control to the supplied value.
Raises BindingError() if control is not supported.
control - QWidget based control that takes the new value
value - A QVariant holding the value
"""
if isinstance(control, QCalendarWidget):
control.setSelectedDate(QDate.fromString(value.toString(), Qt.ISODate))
elif isinstance(control, QListWidget):
items = control.findItems(value.toString(), Qt.MatchExactly)
try:
control.setCurrentItem(items[0])
control.currentItemChanged.emit(None, items[0])
except IndexError:
pass
elif isinstance(control, QLineEdit) or isinstance(control, QTextEdit):
control.setText(value.toString())
elif isinstance(control, QCheckBox) or isinstance(control, QGroupBox):
control.setChecked(value.toBool())
elif isinstance(control, QPlainTextEdit):
control.setPlainText(value.toString())
elif isinstance(control, QComboBox):
# Add items stored in the database
query = QSqlQuery()
query.prepare("SELECT value FROM ComboBoxItems WHERE control = :contorl")
query.bindValue(":control", control.objectName())
query.exec_()
while query.next():
newvalue = query.value(0).toString()
if not newvalue.isEmpty():
control.addItem(newvalue)
itemindex = control.findTe
At the moment, I have the bind and unbind code which uses
if/elif statements to work out the control type and then use the correct methods to bind the value, like so:```
def bindValueToControl(self, control, value):
"""
Binds a control to the supplied value.
Raises BindingError() if control is not supported.
control - QWidget based control that takes the new value
value - A QVariant holding the value
"""
if isinstance(control, QCalendarWidget):
control.setSelectedDate(QDate.fromString(value.toString(), Qt.ISODate))
elif isinstance(control, QListWidget):
items = control.findItems(value.toString(), Qt.MatchExactly)
try:
control.setCurrentItem(items[0])
control.currentItemChanged.emit(None, items[0])
except IndexError:
pass
elif isinstance(control, QLineEdit) or isinstance(control, QTextEdit):
control.setText(value.toString())
elif isinstance(control, QCheckBox) or isinstance(control, QGroupBox):
control.setChecked(value.toBool())
elif isinstance(control, QPlainTextEdit):
control.setPlainText(value.toString())
elif isinstance(control, QComboBox):
# Add items stored in the database
query = QSqlQuery()
query.prepare("SELECT value FROM ComboBoxItems WHERE control = :contorl")
query.bindValue(":control", control.objectName())
query.exec_()
while query.next():
newvalue = query.value(0).toString()
if not newvalue.isEmpty():
control.addItem(newvalue)
itemindex = control.findTe
Solution
To expand a little further on part of sky py's answer, you could try something like the following
You could then set up a dictionary mapping the control type to the appropriate handler:
So your main block of if..elif.. becomes
You'll unfortunately need to keep the
class BaseControlHandler:
def __init__( self, control ):
self.control = control
def bind( self, value ):
raise SuitableException()
def unbind( self ):
raise SuitableException()
class LineEditHandler( BaseControlHandler ):
def __init__( self, control ):
BaseControlHandler.__init__( self, control )
def bind( self, value ):
self.control.setText(value.toString())
def unbind( self ):
return self.control.text()
class CheckBoxHandler( BaseContolHandler ):
# etcYou could then set up a dictionary mapping the control type to the appropriate handler:
handlers = { QtLineEdit: LineEditHandler, QtCheckBox: CheckBoxHandler, ... }So your main block of if..elif.. becomes
for ctltype in handlers:
if isinstance( control, ctltype ):
ctl = handlers[ctltype]( control )
ctl.bind( value ) # or unbind
breakYou'll unfortunately need to keep the
handlers= line and the subclasses in step together.Code Snippets
class BaseControlHandler:
def __init__( self, control ):
self.control = control
def bind( self, value ):
raise SuitableException()
def unbind( self ):
raise SuitableException()
class LineEditHandler( BaseControlHandler ):
def __init__( self, control ):
BaseControlHandler.__init__( self, control )
def bind( self, value ):
self.control.setText(value.toString())
def unbind( self ):
return self.control.text()
class CheckBoxHandler( BaseContolHandler ):
# etchandlers = { QtLineEdit: LineEditHandler, QtCheckBox: CheckBoxHandler, ... }for ctltype in handlers:
if isinstance( control, ctltype ):
ctl = handlers[ctltype]( control )
ctl.bind( value ) # or unbind
breakContext
StackExchange Code Review Q#16454, answer score: 3
Revisions (0)
No revisions yet.