Merge pull request #253 from ares89/master

在行情订阅中,增加了编辑订阅合约的功能
This commit is contained in:
vn.py 2017-03-08 22:50:08 +08:00 committed by GitHub
commit f2dba02243
8 changed files with 881 additions and 229 deletions

View File

@ -1,30 +1,90 @@
{ {
"working": false, "working": true,
"tick": [
"tick":
[ [
["m1609", "XSPEED"], "au1706",
["IF1606", "SGIT"], "CTP"
["IH1606", "SGIT"],
["IH1606", "SGIT"],
["IC1606", "SGIT"],
["IC1606", "SGIT"],
["600036", "LTS", "SZSE"],
["EUR.USD", "IB", "IDEALPRO", "USD", "外汇"]
], ],
"bar":
[ [
["IF1605", "SGIT"], "a1705",
["IF1606", "SGIT"], "CTP"
["IH1606", "SGIT"],
["IH1606", "SGIT"],
["IC1606", "SGIT"],
["IC1606", "SGIT"]
], ],
[
"active": "m1705",
{ "CTP"
],
[
"bu1706",
"CTP"
],
[
"SR705",
"CTP"
],
[
"TA705",
"CTP"
],
[
"MA705",
"CTP"
],
[
"RM705",
"CTP"
],
[
"FG705",
"CTP"
],
[
"OI705",
"CTP"
]
],
"bar": [
[
"au1706",
"CTP"
],
[
"a1705",
"CTP"
],
[
"m1705",
"CTP"
],
[
"bu1706",
"CTP"
],
[
"SR705",
"CTP"
],
[
"TA705",
"CTP"
],
[
"MA705",
"CTP"
],
[
"RM705",
"CTP"
],
[
"FG705",
"CTP"
],
[
"OI705",
"CTP"
]
],
"active": {
"IF0000": "IF1605", "IF0000": "IF1605",
"IH0000": "IH1605", "IH0000": "IH1605",
"IC0000": "IC1605" "IC0000": "IC1605"

View File

@ -6,18 +6,15 @@
使用DR_setting.json来配置需要收集的合约以及主力合约代码 使用DR_setting.json来配置需要收集的合约以及主力合约代码
''' '''
import copy
import json import json
import os import os
import copy from datetime import datetime
from collections import OrderedDict
from datetime import datetime, timedelta
from Queue import Queue
from threading import Thread
from eventEngine import *
from vtGateway import VtSubscribeReq, VtLogData
from drBase import * from drBase import *
from eventEngine import *
from vtFunction import todayDate from vtFunction import todayDate
from vtGateway import VtSubscribeReq, VtLogData
######################################################################## ########################################################################
@ -54,6 +51,17 @@ class DrEngine(object):
# 载入设置,订阅行情 # 载入设置,订阅行情
self.loadSetting() self.loadSetting()
def saveSetting(self, setting):
"""保存设置"""
setting['working'] = self.working
with open(self.settingFileName, 'w') as f:
try:
str = json.dumps(setting, indent=2)
f.write(str)
except:
pass
return True
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def loadSetting(self): def loadSetting(self):
"""载入设置""" """载入设置"""
@ -61,8 +69,8 @@ class DrEngine(object):
drSetting = json.load(f) drSetting = json.load(f)
# 如果working设为False则不启动行情记录功能 # 如果working设为False则不启动行情记录功能
working = drSetting['working'] self.working = drSetting['working']
if not working: if not self.working:
return return
if 'tick' in drSetting: if 'tick' in drSetting:

View File

@ -0,0 +1,400 @@
# encoding: UTF-8
'''
行情记录模块相关的GUI控制组件
'''
import json
import re
import sys
from PyQt4.QtGui import QTreeView
from dataRecorder.drEngine import DrEngine
from eventEngine import *
from uiBasicWidget import QtGui, QtCore
from util.UiUtil import CheckBoxDelegate, ComboDelegate
reload(sys)
sys.setdefaultencoding("utf8")
class TreeItem(object):
def __init__(self, data, parent=None):
self.parentItem = parent
self.itemData = data
self.childItems = []
def appendChild(self, item):
self.childItems.append(item)
def extendChild(self, item):
self.childItems.extend(item)
def child(self, row):
return self.childItems[row]
def childCount(self):
return len(self.childItems)
def columnCount(self):
return len(self.itemData)
def data(self, column):
try:
return self.itemData[column]
except IndexError:
return None
def parent(self):
return self.parentItem
def row(self):
if self.parentItem:
return self.parentItem.childItems.index(self)
return 0
def setData(self, column, value):
if column < 0 or column >= len(self.itemData):
return False
self.itemData[column] = value
return True
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self, parent=None):
super(TreeModel, self).__init__(parent)
self.rootItem = TreeItem([u"合约", u"Tick", u"Bar", u"主力", u"交易所", u"接口"])
def rootItem(self):
return self.rootItem
def setDataSource(self, data):
self.rootItem.extendChild(data)
def columnCount(self, parent):
if parent.isValid():
return parent.internalPointer().columnCount()
else:
return self.rootItem.columnCount()
def setData(self, index, value, role=None):
item = index.internalPointer()
if item is None:
return False
if index.column() == 5:
result = item.setData(index.column(), value)
if result:
self.dataChanged.emit(index, index)
# 如果第一条
if item.parentItem == self.rootItem:
for row in range(item.childCount()):
childIndex = self.index(row, index.column(), index)
self.setData(childIndex, value, QtCore.Qt.DisplayRole)
if index.column() in [1, 2, 3] and role == QtCore.Qt.CheckStateRole:
result = item.setData(index.column(), True if value == QtCore.Qt.Checked else False)
if result:
self.dataChanged.emit(index, index)
# 如果第一条
if item.parentItem == self.rootItem and index.column() in [1, 2]:
for row in range(item.childCount()):
childIndex = self.index(row, index.column(), index)
self.setData(childIndex, value, QtCore.Qt.CheckStateRole)
if value == QtCore.Qt.Checked and index.column() == 3:
for row in range(item.parentItem.childCount()):
if row != index.row():
siblingIndex = self.index(row, index.column(), index.parent())
self.setData(siblingIndex, QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole)
return True
def data(self, index, role):
if not index.isValid():
return None
item = index.internalPointer()
if role == QtCore.Qt.TextAlignmentRole:
return QtCore.Qt.AlignCenter
if role == QtCore.Qt.CheckStateRole and (
index.column() in [1, 2] or index.column() == 3 and item.parentItem != self.rootItem):
return QtCore.Qt.Checked if item.data(index.column()) == True else QtCore.Qt.Unchecked
if role != QtCore.Qt.DisplayRole or index.column() in [3, 4] and item.parentItem == self.rootItem:
return None
return item.data(index.column())
def flags(self, index):
if not index.isValid():
return QtCore.Qt.NoItemFlags
if index.column() in [0, 4]:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
if index.column() in [5]:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
item = index.internalPointer()
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 | QtCore.Qt.ItemIsEditable
def headerData(self, section, orientation, role):
if orientation == QtCore.Qt.Horizontal:
if role == QtCore.Qt.DisplayRole:
return self.rootItem.data(section)
elif role == QtCore.Qt.TextAlignmentRole:
return QtCore.Qt.AlignCenter
return None
def index(self, row, column, parent):
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
if parent is None or not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QtCore.QModelIndex()
def parent(self, index):
if not index.isValid():
return QtCore.QModelIndex()
childItem = index.internalPointer()
parentItem = childItem.parent()
if parentItem == self.rootItem:
return QtCore.QModelIndex()
return self.createIndex(parentItem.row(), 0, parentItem)
def rowCount(self, parent):
if parent.column() > 0:
return 0
if not parent.isValid():
parentItem = self.rootItem
else:
parentItem = parent.internalPointer()
return parentItem.childCount()
def hasIndex(self, row, column, parentIndex=None, *args, **kwargs):
if row < 0 or column > self.rootItem.columnCount():
return False
return True
class DrEditWidget(QtGui.QWidget):
"""行情数据记录引擎管理组件"""
signal = QtCore.pyqtSignal(type(Event()))
def __init__(self, drWidget, mainEngine, eventEngine, parent=None):
"""Constructor"""
super(DrEditWidget, self).__init__(parent)
self.drWidget = drWidget
self.mainEngine = mainEngine
self.eventEngine = eventEngine
self.hasChanged = False
# 保存合约详细信息的字典
self.contractDict = {}
self.initUi()
self.updateSetting()
self.loadData()
self.registerEvent()
def closeEvent(self, QCloseEvent):
if self.hasChanged:
self.drWidget.restart()
def initUi(self):
vbox = QtGui.QVBoxLayout()
vline = QtGui.QHBoxLayout()
vline.setSpacing(2)
btnTickAll = QtGui.QPushButton(u"全部记录Tick", self)
btnBarAll = QtGui.QPushButton(u'全部记录Bar', self)
btnSaveAll = QtGui.QPushButton(u'保存设置(重启后生效)', self)
btnTickAll.clicked.connect(self.selectAllTick)
btnBarAll.clicked.connect(self.selectAllBar)
btnSaveAll.clicked.connect(self.saveSetting)
vline.addWidget(btnTickAll)
vline.addWidget(btnBarAll)
vline.addWidget(btnSaveAll)
vbox.addLayout(vline)
self.qTreeView = QTreeView()
self.model = TreeModel()
self.qTreeView.setModel(self.model)
self.qTreeView.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
self.qTreeView.setItemDelegateForColumn(1, CheckBoxDelegate(self))
self.qTreeView.setItemDelegateForColumn(2, CheckBoxDelegate(self))
self.qTreeView.setItemDelegateForColumn(3, CheckBoxDelegate(self))
self.qTreeView.setItemDelegateForColumn(5, ComboDelegate(self, ["CTP", "LTS", "XTP", "FEMAS", "XSPEED", "QDP",
"KSOTP", "KSGOLD", "SGIT"]))
vbox.addWidget(self.qTreeView)
self.setLayout(vbox)
def getContractChineseName(self, str):
line = str.strip().decode('utf-8', 'ignore') # 处理前进行相关的处理包括转换成Unicode等
p2 = re.compile(ur'[^\u4e00-\u9fa5]') # 中文的编码范围是:\u4e00到\u9fa5
zh = " ".join(p2.split(line)).strip()
zh = ",".join(zh.split())
outStr = zh # 经过相关处理后得到中文的文本
return outStr
def loadData(self):
child = []
tick = {}
bar = {}
active = []
with open(self.mainEngine.drEngine.settingFileName) as f:
drSetting = json.load(f)
if 'tick' in drSetting:
l = drSetting['tick']
for setting in l:
tick[setting[0]] = setting[1]
if 'bar' in drSetting:
l = drSetting['bar']
for setting in l:
bar[setting[0]] = setting[1]
if 'active' in drSetting:
d = drSetting['active']
for activeSymbol, symbol in d.items():
active.append(symbol)
contractDict = {}
contracts = self.mainEngine.getAllContracts()
for contract in contracts:
contractName = self.getContractChineseName(contract.name)
gateWayName = u"CTP"
hasTick = tick.has_key(contract.symbol)
hasBar = bar.has_key(contract.symbol)
hasActive = contract.symbol in active
if hasTick:
gateWayName = tick[contract.symbol]
elif hasBar:
gateWayName = bar[contract.symbol]
if contractDict.has_key(contractName):
parentItem = contractDict[contractName]
item = TreeItem([contract.symbol, hasTick, hasBar, hasActive, contract.exchange, gateWayName],
parentItem)
parentItem.appendChild(item)
else:
item = TreeItem([contractName, False, False, False, contract.exchange, gateWayName],
self.model.rootItem)
contractDict[contractName] = item
child.append(item)
subItem = TreeItem([contract.symbol, hasTick, hasBar, hasActive, contract.exchange, gateWayName], item)
item.appendChild(subItem)
# yumi = TreeItem([u"玉米", False, False, False, "SH", "CTP"], self.model.rootItem)
# yumi.appendChild(TreeItem([u"c1705", False, False, False, "SH", "CTP"], yumi))
# yumi.appendChild(TreeItem([u"c1703", False, False, False, "SH", "CTP"], yumi))
# yumi.appendChild(TreeItem([u"c1707", False, False, False, "SH", "CTP"], yumi))
# yumi.appendChild(TreeItem([u"c1709", False, False, False, "SH", "CTP"], yumi))
# dianfen = TreeItem([u"淀粉", False, False, False, "SH", "CTP"], self.model.rootItem)
# dianfen.appendChild(TreeItem([u"d1705", False, False, False, "SH", "CTP"], dianfen))
# dianfen.appendChild(TreeItem([u"d1703", False, False, False, "SH", "CTP"], dianfen))
# dianfen.appendChild(TreeItem([u"d1707", False, False, False, "SH", "CTP"], dianfen))
# dianfen.appendChild(TreeItem([u"d1709", False, False, False, "SH", "CTP"], dianfen))
#
# child.append(yumi)
# child.append(dianfen)
self.model.setDataSource(child)
self.qTreeView.expandAll()
def saveSetting(self):
setting = {}
setting["tick"] = []
setting["bar"] = []
setting["active"] = {}
queue = Queue()
queue.put(self.model.rootItem)
while queue.qsize() > 0:
item = queue.get()
for child in item.childItems:
queue.put(child)
if item.parentItem is not None and item.parentItem != self.model.rootItem:
name = item.data(0)
interface = item.data(5)
if item.data(1):
setting["tick"].append([name, interface])
if item.data(2):
setting["bar"].append([name, interface])
if item.data(3):
setting["active"][item.parentItem.data(0)] = name
if self.mainEngine.drEngine.saveSetting(setting):
self.hasChanged = True
self.close()
def selectAllTick(self):
self.selectAll(True, False, True)
def selectAllBar(self):
self.selectAll(False, True, True)
def selectAll(self, tick=False, bar=False, select=False):
column = None
if tick:
column = 1
if bar:
column = 2
for row in range(self.model.rootItem.childCount()):
childIndex = self.model.index(row, column, None)
self.model.setData(childIndex, QtCore.Qt.Unchecked if select == False else QtCore.Qt.Checked,
QtCore.Qt.CheckStateRole)
def updateSetting(self):
pass
def updateContract(self, event):
"""更新合约数据"""
contract = event.dict_['data']
self.contractDict[contract.vtSymbol] = contract
self.contractDict[contract.symbol] = contract # 使用常规代码(不包括交易所)可能导致重复
# ----------------------------------------------------------------------
def registerEvent(self):
"""注册事件监听"""
self.signal.connect(self.updateContract)
self.eventEngine.register(EVENT_CONTRACT, self.signal.emit)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
view = DrEditWidget(None, DrEngine, EventEngine)
view.setFixedSize(650, 500)
view.show()
sys.exit(app.exec_())

View File

@ -6,8 +6,9 @@
import json import json
from uiBasicWidget import QtGui, QtCore from dataRecorder.uiDrEdit import DrEditWidget
from eventEngine import * from eventEngine import *
from uiBasicWidget import QtGui, QtCore
######################################################################## ########################################################################
@ -38,11 +39,12 @@ class DrEngineManager(QtGui.QWidget):
signal = QtCore.pyqtSignal(type(Event())) signal = QtCore.pyqtSignal(type(Event()))
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def __init__(self, drEngine, eventEngine, parent=None): def __init__(self, mainEngine, eventEngine, parent=None):
"""Constructor""" """Constructor"""
super(DrEngineManager, self).__init__(parent) super(DrEngineManager, self).__init__(parent)
self.drEngine = drEngine self.mainEngine = mainEngine
self.drEngine = mainEngine.drEngine
self.eventEngine = eventEngine self.eventEngine = eventEngine
self.initUi() self.initUi()
@ -97,11 +99,20 @@ class DrEngineManager(QtGui.QWidget):
grid.addWidget(self.barTable, 1, 1) grid.addWidget(self.barTable, 1, 1)
grid.addWidget(self.activeTable, 1, 2) grid.addWidget(self.activeTable, 1, 2)
btnEdit = QtGui.QPushButton(u'编辑', self)
vbox = QtGui.QVBoxLayout() vbox = QtGui.QVBoxLayout()
vbox.addLayout(grid) vbox.addLayout(grid)
vline = QtGui.QHBoxLayout()
vline.addWidget(btnEdit)
vbox.addLayout(vline)
vbox.addWidget(self.logMonitor) vbox.addWidget(self.logMonitor)
self.setLayout(vbox) self.setLayout(vbox)
btnEdit.clicked.connect(self.openDr)
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def updateLog(self, event): def updateLog(self, event):
"""更新日志""" """更新日志"""
@ -118,6 +129,14 @@ class DrEngineManager(QtGui.QWidget):
#---------------------------------------------------------------------- #----------------------------------------------------------------------
def updateSetting(self): def updateSetting(self):
"""显示引擎行情记录配置""" """显示引擎行情记录配置"""
self.tickTable.clearContents()
self.tickTable.setRowCount(0)
self.barTable.clearContents()
self.barTable.setRowCount(0)
self.activeTable.clearContents()
self.activeTable.setRowCount(0)
with open(self.drEngine.settingFileName) as f: with open(self.drEngine.settingFileName) as f:
drSetting = json.load(f) drSetting = json.load(f)
@ -145,11 +164,16 @@ class DrEngineManager(QtGui.QWidget):
self.activeTable.setItem(0, 0, TableCell(activeSymbol)) self.activeTable.setItem(0, 0, TableCell(activeSymbol))
self.activeTable.setItem(0, 1, TableCell(symbol)) self.activeTable.setItem(0, 1, TableCell(symbol))
# ----------------------------------------------------------------------
def openDr(self):
"""打开行情数据记录组件"""
self.mDrEditWidget = DrEditWidget(self,self.mainEngine, self.eventEngine)
self.mDrEditWidget.setWindowTitle(u"编辑订阅")
self.mDrEditWidget.setFixedSize(800,800)
self.mDrEditWidget.show()
def restart(self):
pass
# self.drEngine.stop()
# self.updateSetting()
# self.mainEngine.drEngine = DrEngine(self.mainEngine, self.mainEngine.eventEngine)

View File

@ -1,13 +1,11 @@
# encoding: UTF-8 # encoding: UTF-8
import json
import csv import csv
import os
from collections import OrderedDict from collections import OrderedDict
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt
from eventEngine import *
from vtFunction import * from vtFunction import *
from vtGateway import * from vtGateway import *
@ -53,6 +51,22 @@ class BasicCell(QtGui.QTableWidgetItem):
self.setText(text) self.setText(text)
########################################################################
class CheckBoxCell(QtGui.QTableWidgetItem):
"""用来显示复选框的单元格"""
def __init__(self, isChecked=False, mainEngine=None):
"""Constructor"""
super(CheckBoxCell, self).__init__()
self.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
self.setStauts(isChecked)
def setStauts(self, isChecked=False):
if not isChecked:
self.setCheckState(Qt.Unchecked)
else:
self.setCheckState(Qt.Checked)
######################################################################## ########################################################################
class NumCell(QtGui.QTableWidgetItem): class NumCell(QtGui.QTableWidgetItem):
"""用来显示数字的单元格""" """用来显示数字的单元格"""
@ -431,7 +445,7 @@ class MarketMonitor(BasicMonitor):
self.setFont(BASIC_FONT) self.setFont(BASIC_FONT)
# 设置允许排序 # 设置允许排序
self.setSorting(True) self.setSorting(False)
# 初始化表格 # 初始化表格
self.initTable() self.initTable()
@ -1116,8 +1130,10 @@ class ContractMonitor(BasicMonitor):
contract = d[key] contract = d[key]
for n, header in enumerate(self.headerList): for n, header in enumerate(self.headerList):
content = safeUnicode(contract.__getattribute__(header))
cellType = self.headerDict[header]['cellType'] cellType = self.headerDict[header]['cellType']
content = None
if (hasattr(contract, header)):
content = safeUnicode(contract.__getattribute__(header))
cell = cellType(content) cell = cellType(content)
if self.font: if self.font:

View File

@ -2,10 +2,10 @@
import psutil import psutil
from uiBasicWidget import *
from ctaAlgo.uiCtaWidget import CtaEngineManager from ctaAlgo.uiCtaWidget import CtaEngineManager
from dataRecorder.uiDrWidget import DrEngineManager from dataRecorder.uiDrWidget import DrEngineManager
from riskManager.uiRmWidget import RmEngineManager from riskManager.uiRmWidget import RmEngineManager
from uiBasicWidget import *
######################################################################## ########################################################################
class MainWindow(QtGui.QMainWindow): class MainWindow(QtGui.QMainWindow):
@ -197,7 +197,7 @@ class MainWindow(QtGui.QMainWindow):
try: try:
self.widgetDict['drM'].showMaximized() self.widgetDict['drM'].showMaximized()
except KeyError: except KeyError:
self.widgetDict['drM'] = DrEngineManager(self.mainEngine.drEngine, self.eventEngine) self.widgetDict['drM'] = DrEngineManager(self.mainEngine, self.eventEngine)
self.widgetDict['drM'].showMaximized() self.widgetDict['drM'].showMaximized()
#---------------------------------------------------------------------- #----------------------------------------------------------------------

144
vn.trader/util/UiUtil.py Normal file
View File

@ -0,0 +1,144 @@
from PyQt4 import QtCore
from PyQt4.QtGui import QStyle, QStyledItemDelegate, QStyleOptionButton, QApplication, QItemDelegate, QComboBox, \
QItemEditorCreatorBase
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())
class ComboDelegate(QItemDelegate):
def __init__(self, parent, dataList=[]):
QItemDelegate.__init__(self, parent)
self.dataList = dataList
def createEditor(self, parent, option, index):
combo = QComboBox(parent)
combo.addItems(self.dataList)
return combo
def setEditorData(self, editor, index):
text = index.data().toString()
index = editor.findText(text)
editor.setCurrentIndex(index)
def setModelData(self, editor, model, index):
model.setData(index, str(editor.itemText(editor.currentIndex())))
def updateEditorGeometry(self, editor, option, index):
print option, option.rect
editor.setGeometry(option.rect)
class GateWayListEditor(QComboBox):
def __init__(self, widget=None, dataList=[]):
super(GateWayListEditor, self).__init__(widget)
self.dataList = dataList
self.populateList()
def getGateWay(self):
gateWay = self.itemData(self.currentIndex(), QtCore.Qt.DisplayRole)
return gateWay
def setGateWay(self, gateWay):
self.setCurrentIndex(self.findData(gateWay, QtCore.Qt.DisplayRole))
def populateList(self):
for i, gateWayName in enumerate(self.dataList):
self.insertItem(i, gateWayName)
self.setItemData(i, gateWayName, QtCore.Qt.DisplayRole)
class GateWayListItemEditorCreator(QItemEditorCreatorBase):
def createWidget(self, parent):
return GateWayListEditor(parent, ["CTP", "LTS", "XTP", "FEMAS", "XSPEED", "QDP", "KSOTP", "KSGOLD", "SGIT"])

View File