diff --git a/vn.trader/dataRecorder/uiDrEdit.py b/vn.trader/dataRecorder/uiDrEdit.py index 64f6b2f6..f0a5f23f 100644 --- a/vn.trader/dataRecorder/uiDrEdit.py +++ b/vn.trader/dataRecorder/uiDrEdit.py @@ -11,6 +11,7 @@ from PyQt4.QtGui import QTreeView from dataRecorder.drEngine import DrEngine from eventEngine import * from uiBasicWidget import QtGui, QtCore +from util.UiUtil import CheckBoxDelegate reload(sys) sys.setdefaultencoding("utf8") @@ -127,7 +128,7 @@ class TreeModel(QtCore.QAbstractItemModel): if index.column() == 3 and item.parentItem == self.rootItem: return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable - return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable + return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEditable def headerData(self, section, orientation, role): if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: @@ -225,6 +226,9 @@ class DrEditWidget(QtGui.QWidget): self.qTreeView = QTreeView() self.model = TreeModel() self.qTreeView.setModel(self.model) + self.qTreeView.setItemDelegateForColumn(1, CheckBoxDelegate(self)) + self.qTreeView.setItemDelegateForColumn(2, CheckBoxDelegate(self)) + self.qTreeView.setItemDelegateForColumn(3, CheckBoxDelegate(self)) vbox.addWidget(self.qTreeView) self.setLayout(vbox) diff --git a/vn.trader/util/UiUtil.py b/vn.trader/util/UiUtil.py new file mode 100644 index 00000000..8efcc41a --- /dev/null +++ b/vn.trader/util/UiUtil.py @@ -0,0 +1,96 @@ +from PyQt4 import QtCore +from PyQt4.QtGui import QStyle, QStyledItemDelegate, QStyleOptionButton, QApplication, QItemDelegate + + +class CheckBoxDelegate(QStyledItemDelegate): + """ + A delegate that places a fully functioning QCheckBox in every + cell of the column to which it's applied + """ + + def __init__(self, parent): + QItemDelegate.__init__(self, parent) + + def createEditor(self, parent, option, index): + ''' + Important, otherwise an editor is created if the user clicks in this cell. + ** Need to hook up a signal to the model + ''' + return None + + def paint(self, painter, option, index): + ''' + Paint a checkbox without the label. + ''' + data = index.model().data(index, QtCore.Qt.CheckStateRole) + if not data in [QtCore.Qt.Unchecked, QtCore.Qt.Checked]: + return + checked = data == QtCore.Qt.Checked + check_box_style_option = QStyleOptionButton() + + if index.flags() & QtCore.Qt.ItemIsEditable == QtCore.Qt.ItemIsEditable: + check_box_style_option.state |= QStyle.State_Enabled + else: + check_box_style_option.state |= QStyle.State_ReadOnly + + if checked: + check_box_style_option.state |= QStyle.State_On + else: + check_box_style_option.state |= QStyle.State_Off + + check_box_style_option.rect = self.getCheckBoxRect(option) + + # this will not run - hasFlag does not exist + # if not index.model().hasFlag(index, QtCore.Qt.ItemIsEditable): + # check_box_style_option.state |= QStyle.State_ReadOnly + + # check_box_style_option.state |= QStyle.State_Enabled + + QApplication.style().drawControl(QStyle.CE_CheckBox, check_box_style_option, painter) + + def editorEvent(self, event, model, option, index): + ''' + Change the data in the model and the state of the checkbox + if the user presses the left mousebutton or presses + Key_Space or Key_Select and this cell is editable. Otherwise do nothing. + ''' + # print 'Check Box editor Event detected : ' + if index.flags() & QtCore.Qt.ItemIsEditable != QtCore.Qt.ItemIsEditable: + return False + + # print 'Check Box edior Event detected : passed first check' + # Do not change the checkbox-state + if event.type() == QtCore.QEvent.MouseButtonRelease or event.type() == QtCore.QEvent.MouseButtonDblClick: + if event.button() != QtCore.Qt.LeftButton or not self.getCheckBoxRect(option).contains(event.pos()): + return False + if event.type() == QtCore.QEvent.MouseButtonDblClick: + return True + elif event.type() == QtCore.QEvent.KeyPress: + if event.key() != QtCore.Qt.Key_Space and event.key() != QtCore.Qt.Key_Select: + return False + else: + return False + + # Change the checkbox-state + self.setModelData(None, model, index) + return True + + def setModelData(self, editor, model, index): + ''' + The user wanted to change the old state in the opposite. + ''' + # print 'SetModelData' + newValue = not index.data().toBool() + # print 'New Value : {0}'.format(newValue) + model.setData(index, QtCore.Qt.Checked if newValue else QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole) + + def getCheckBoxRect(self, option): + check_box_style_option = QStyleOptionButton() + check_box_rect = QApplication.style().subElementRect(QStyle.SE_CheckBoxIndicator, check_box_style_option, None) + check_box_point = QtCore.QPoint(option.rect.x() + + option.rect.width() / 2 - + check_box_rect.width() / 2, + option.rect.y() + + option.rect.height() / 2 - + check_box_rect.height() / 2) + return QtCore.QRect(check_box_point, check_box_rect.size()) diff --git a/vn.trader/util/__init__.py b/vn.trader/util/__init__.py new file mode 100644 index 00000000..e69de29b