ich habe ein Problem mit den MouseEvents und ich weiß schon nicht mehr weiter. Vielleicht steh ich auch auf dem Schlauch und deswegen wende ich mich an euch, vielleicht könnt ihr mir ja helfen. Ich habe dieses Projekt erst vor kurzem übernommen und kenne mich mit der GUI Programmierung in Python noch nicht so ganz aus.
Zur Erklärung ich hab eine Gui die Module auflistet und auch zeigt, ob zu dem Modul eine Dokumentation vorhanden ist. Dies wird in Form eines kleinen Symbols gekennzeichnet.
Als Beispiel, damit ich seh ob es funktioniert, hab ich mir ein keyPressEvent Funktion geschrieben, dieses Event kommt durch. Das mousePressEvent oder mouseMoveEvent oder mouseHoverEvent kommt einfach nicht durch. ich hoffe ihr könnt mir helfen.
Das ist meine Klasse, meine funktionen stehen unten. Mir geht es hier hauptsächlich darum, dass mouseHoverEvent zu bekommen, wenn ich über das Doc-icon fahre, damit ich da den Mousezeiger ändern kann.
Ich hoffe, dass ich alles verständlich erklärt habe.
Viele Grüße,
Bianca
Code: Alles auswählen
class ModuleLib(CentralWidgetBase, QWidget):
warnColor='#999900'#Qt.darkYellow
errColor=Qt.red
normalColor='#000000'#Qt.darkGreen
applyFilterSignal = pyqtSignal(name='applyFilterSignal')
restoreExpansionSignal = pyqtSignal(QModelIndex, dict, name='applyFilterSignal')
def __init__(self, communicator):
QWidget.__init__(self)
CentralWidgetBase.__init__(self, communicator)
self.sM=self.communicator.getObject('SettingsManager')
self.urlIcon=images['url'].as_('icon')
self.buildGui()
self.cache = {
'autoUpdatePkgInfo': True,
}
self.communicator.registerListener('pkgsInfoReady', self.updateModuleList)
self.communicator.registerFunction(self.getLastScannedInfoTreeItem,localOnly=True)
self.lastScannedPkgsInfo={}
self.lastScannedIndex={}
self.infoItems={}
self.filterStr=''
self.filterChangedDelayTimer=QTimer()
self.filterChangedDelayTimer.setSingleShot(True)
self.filterChangedDelayTimer.timeout.connect(self.onApplyFilter)
self.applyFilterSignal.connect(self.onApplyFilter)
self.restoreExpansionSignal.connect(self.restoreExpansion)
self.infoTreeItems={}
def title(cls):
return 'Module Library'
@classmethod
def functionalPlugin(cls):
return 'SupervisingPackageManager'
def getLastScannedInfoTreeItem(self, infoKey):
return self.infoTreeItems.get(infoKey, None)
def onPluginsCreated(self, savedInstanceState=None):
self.packageManager = self.communicator.getObject('SupervisingPackageManager')
self.setModuleInfoViewMarkPattern=self.communicator.getFunction('setModuleInfoViewMarkPattern')
if savedInstanceState is not None:
self.cache.update(savedInstanceState)
self.updateGui()
def onSaveInstanceState(self):
self.cache['autoUpdatePkgInfo'] = self.autoUpdateCheckBox.isChecked()
return self.cache
def updateGui(self):
self.autoUpdateCheckBox.setChecked(self.cache['autoUpdatePkgInfo'])
pM = self.communicator.getObject('PluginManager')
editors = pM.getPlugins(PackageEditorBase)
if len(editors) == 0:
self.editorsBox.setHidden(True)
else:
editorsBoxLayout = FlowLayout()
self.editorsBox.setLayout(editorsBoxLayout)
for editor in sorted(editors, key=lambda e: e.pkgExt):
editBut = QPushButton(editor.pkgExt)
editorsBoxLayout.addWidget(editBut)
def editPackages(x, e=editor):
CleaningThread(target=e.editPackages).start()
editBut.clicked.connect(editPackages)
if self.autoUpdateCheckBox.isChecked():
self.requestModuleInfo()
# else:
# self.updateModuleList(True, self.packageManager.getLastScannedPkgInfos(), self.packageManager.getLastScannedIndex())
def requestModuleInfo(self):
self.communicator.send('pkgsInfoRequest', newThread=True)
def __generateToolTipMsg(self,notes):
tooltip=''
color=None
pkgWarnString = '\n'.join(note['msg'] for note in notes if note['type'] == 'warning')
if pkgWarnString != '':
tooltip = ('warnings:\n' + pkgWarnString).replace('\n', '\n\t')
color=self.warnColor
pkgErrString = '\n'.join(note['msg'] for note in notes if note['type'] == 'error')
if pkgErrString != '':
tooltip = ('errors:\n' + pkgErrString).replace('\n', '\n\t') + '\n' + tooltip
color=self.errColor
return tooltip, color
def storeExpansion(self, index):
expansions = {}
for i in range(self.filterModel.rowCount(index)):
child = self.filterModel.index(i, 0, index)
if self.moduleTreeView.isExpanded(child):
expansions[self.filterModel.data(child,Qt.DisplayRole)] = self.storeExpansion(child)
return expansions
def restoreExpansion(self,index, expansions):
for i in range(self.filterModel.rowCount(index)):
child = self.filterModel.index(i, 0, index)
subExpansions=expansions.get(self.filterModel.data(child,Qt.DisplayRole),None)
if subExpansions is not None:
self.moduleTreeView.expand(child)
self.restoreExpansion(child, subExpansions)
def updateModuleList(self, fullScan, pkgsInfos, index):
if fullScan:
self.lastScannedPkgsInfo = pkgsInfos
self.lastScannedIndex = index
self.infoTreeItems.clear()
else:
DictTools.update(self.lastScannedPkgsInfo, pkgsInfos)
DictTools.update(self.lastScannedIndex, index)
libTreeInfo={}
for pkg, pkgInfo in self.lastScannedPkgsInfo.items():
pkgInfoItem=InfoTreeItem(key=pkg, value=pkgInfo)
self.infoItems[pkg]=pkgInfoItem
pkgPath = pkgInfo['path']
pkgSearchRoot = pkgInfo['searchRoot']
lib = path.dirname(pkgPath)[len(pkgSearchRoot)+1:].replace('/',':childs:')
if lib == '':
libPkgs = libTreeInfo
parentLibs = []
else:
libInfo = DictTools.get(libTreeInfo,lib)
if libInfo is None:
libInfo = {'childs':{}}
DictTools.set(libTreeInfo, libInfo,lib)
libPkgs=libInfo['childs']
parentLibs =[libInfo]
while ':childs:' in lib:
lib = lib.rsplit(':childs:',1)[0]
parentLibs.append(DictTools.get(libTreeInfo,lib))
notes=pkgInfo['notes']
mods={}
msg,col=self.__generateToolTipMsg(notes)
for libInfo in parentLibs:
if col==self.errColor:
libInfo['color'] = self.errColor
elif col==self.warnColor and libInfo.get('color',None)!= self.errColor:
libInfo['color'] = self.warnColor
elif 'color' not in libInfo:
libInfo['color'] = self.normalColor
pkgEntry = {'childs': mods, 'color': col, 'msg': msg, 'type':'pkg', 'infoKey': pkg,'infoItem':pkgInfoItem}
self.addDocIcon(pkgPath,pkgEntry,pkgInfo)
self.infoTreeItems[pkg]=pkgInfoItem
for pkgModuleInfoKey in pkgInfo['moduleInfoKeys']:
moduleInfoKey = pkg + ':' + pkgModuleInfoKey
module=DictTools.endKey(moduleInfoKey)
msg, col = self.__generateToolTipMsg([note for note in notes if module in note.get('possiblyAffectedModules',[])])
moduleInfoItem=pkgInfoItem.moduleItemList[module]
mods[module]=modEntry={'color': col, 'msg': msg, 'infoKey': moduleInfoKey, 'type':'mod','infoItem':moduleInfoItem}
self.addDocIcon(pkgPath, modEntry, DictTools.get(pkgInfo,pkgModuleInfoKey,{}))
self.infoTreeItems[moduleInfoKey] = moduleInfoItem
libPkgs[pkg]=pkgEntry
expansions = self.storeExpansion(self.moduleTreeView.rootIndex())
self.libDataModel.setPyData(libTreeInfo)
self.restoreExpansionSignal.emit(self.moduleTreeView.rootIndex(), expansions)
self.applyFilterSignal.emit()
self.communicator.send('infoTreeItemsChanged')
def addDocIcon(self,root, itemInfo,info):
doc = info.get('doc', None)
if doc is not None:
if urllib.parse.urlparse(doc).scheme == "":
docPath = doc if path.isabs(doc) else (root + '/' + doc)
if path.exists(docPath):
itemInfo['doc'] = docPath
itemInfo['docIcon'] = QFileIconProvider().icon(QFileInfo(docPath))
else:
self.communicator.warning('documentation "'+docPath+'" could not be found')
else:
itemInfo['doc'] = doc
itemInfo['docIcon'] = self.urlIcon
# def onModuleListItemClicked(self,index):
# if index.isValid():
# moduleListItem=self.filterModel.mapToSource(index).internalPointer()
# if moduleListItem.infoItem is not None:
# self.setModuleInfoViewRootItem(moduleListItem.infoItem, moduleListItem.key)
def onFilterChanged(self,filterStr):
self.filterStr = filterStr.lower()
self.filterChangedDelayTimer.start(500)
def onItemDoubleClicked(self,index):
if not index.isValid():
return
info = index.data(Qt.UserRole)
if index.column() == 0:
infoKey = info.get('infoKey',None)
if infoKey is not None:
splitKey = DictTools.seperatorPattern.split(infoKey)
pkgInfo = self.lastScannedPkgsInfo[splitKey[0]]
if len(splitKey) == 1: # package
webbrowser.open(pkgInfo['path'])
elif index.column() == 1:
doc=info.get('doc',None)
if doc is not None:
webbrowser.open(doc)
def onApplyFilter(self):
withKey=self.searchInclusiveKeysCheckBox.isChecked()
pattern = None
if self.searchRegExCheckBox.isChecked():
if len(self.filterStr)>0:
pattern=re.compile(self.filterStr, re.IGNORECASE | re.DOTALL)
for pkg, pkgInfoItem in self.infoItems.items():
pkgInfoItem.countFilterMatchesRegEx(pattern, withKey)
else:
filterList = self.filterStr.split()
for pkg, pkgInfoItem in self.infoItems.items():
pkgInfoItem.countFilterMatches(filterList, withKey)
if len(filterList)> 0:
pattern = re.compile('|'.join(re.escape(word) for word in filterList), re.IGNORECASE)
if self.libDataModel.rootItem is not None:
self.libDataModel.rootItem.setFilter(pattern)
#self.filterModel.invalidateFilter()
self.filterModel.invalidate()
self.filterModel.sort(0,Qt.AscendingOrder)
self.setModuleInfoViewMarkPattern(pattern, withKey)
self.moduleTreeView.resizeColumnToContents(0)
def buildGui(self):
### main layout
mainLay = QVBoxLayout(self)
self.setLayout(mainLay)
## first row
rowLay = QHBoxLayout()
mainLay.addLayout(rowLay)
# search box
rowLay.addWidget(QLabel('filter:')) # , 0, Qt.AlignLeft)
self.searchLineEdit = QLineEdit()
self.searchLineEdit.textChanged.connect(self.onFilterChanged)
rowLay.addWidget(self.searchLineEdit, 1) # , Qt.AlignLeft)
# search in keys checkbox
self.searchInclusiveKeysCheckBox = QCheckBox('search in keys')
self.searchInclusiveKeysCheckBox.setChecked(True)
self.searchInclusiveKeysCheckBox.stateChanged.connect(self.onApplyFilter)
rowLay.addWidget(self.searchInclusiveKeysCheckBox) # , 0, Qt.AlignRight)
self.searchRegExCheckBox = QCheckBox('regEx')
self.searchRegExCheckBox.setChecked(False)
self.searchRegExCheckBox.stateChanged.connect(self.onApplyFilter)
rowLay.addWidget(self.searchRegExCheckBox) # , 0, Qt.AlignRight)
# auto update checkbox
self.autoUpdateCheckBox = QCheckBox('scan modules on startup')
rowLay.addWidget(self.autoUpdateCheckBox) # , 0, Qt.AlignRight)
# update button
self.updateModuleListButton = QPushButton('scan')
rowLay.addWidget(self.updateModuleListButton)
self.updateModuleListButton.clicked.connect(self.requestModuleInfo)
# module list
self.moduleTreeView = QTreeView()
self.moduleTreeView.setUniformRowHeights(True)
#self.moduleTreeView.header().close()
self.moduleTreeView.setDragEnabled(True)
self.moduleTreeView.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.moduleTreeView.collapsed.connect(lambda x: self.moduleTreeView.resizeColumnToContents(0))
self.moduleTreeView.expanded.connect(lambda x: self.moduleTreeView.resizeColumnToContents(0))
self.moduleTreeView.setExpandsOnDoubleClick(False)
#self.moduleTreeView.clicked.connect(lambda x: self.moduleTreeView.collapse(x) if self.moduleTreeView.isExpanded(x) else self.moduleTreeView.expand(x))
self.moduleTreeView.doubleClicked.connect(self.onItemDoubleClicked)
self.moduleTreeView.setMouseTracking(True)
#self.setCursor(Qt.PointingHandCursor)
self.libDataModel = ModuleLibTreeModel()
self.filterModel=ModuleLibTreeFilter()
self.filterModel.setSourceModel(self.libDataModel)
self.filterModel.setDynamicSortFilter(True)
self.moduleTreeView.setModel(self.filterModel)
mainLay.addWidget(self.moduleTreeView)
# editors
self.editorsBox = QGroupBox('edit packages')
mainLay.addWidget(self.editorsBox)
def keyPressEvent(self, keyEvent):
if keyEvent.matches(QKeySequence.Delete):
self.communicator.log('jawoll')
else:
self.communicator.log('moeeep')
super().keyPressEvent(keyEvent)
def mousePressEvent(self, mouseEvent):
if mouseEvent.button() == Qt.LeftButton:
self.communicator.log('jawoll')
elif mouseEvent.button() == Qt.RightButton:
self.communicator.log('rechts')
super().mousePressEvent(mouseEvent)