mit beiegügtem Code (Python 3.3.1 PyQt4.10) sollte mein Verständnisproblem ersichtlich sein:
Wie können auf einen Mouse-Klick (rechts) in einem Unterfenster (hier definiert in loglistwidget.py) reagiert werden, und dabei Daten aus dem Unterfenster im Hauptfenster (MainWindow) weiter bearbeitet werden?
In class MainWindow hängt self.listWidget als logDockWidget von MainWindow. In listWidget werden die in MainWindow ausgelösten Operationen gelogt und angezeigt. Ein Rechts-Klick im logWidget öffnet den Frage-Dialog, ob die darin gelogten Operationen tatsächlich gelöscht werden sollen. Dazu wir die Instanz self.listWidget von der eigens programmierten class LogListWidget() abegleitet. In dessen Methode mouseReleaseEvent() wird kontrolliert, ob die rechte Maus-Taste nach Klick wieder losgelassen wird. In diesem Fall wird der Inhalt von self.listWidget gelöscht.
Nun möchte ich die in self.mouseEventList (Attribut von class LogListWidget() ) gepeicherten Daten in MainWindow weiter bearbeiten können.
Welchen Code muss ich dazu eventuell in class LogListWidget() ergänzen um das Signal (Event) rightMouseButtonReleased zu werfen (emit)?
Und mit welchem Code reagiere ich in MainWindow auf das oben genannte Signal?
Meine Versuche in MainWindow auf in self.listWidget ausgelöste Events gemäß http://zetcode.com/tutorials/pyqt4/germ ... ndsignals/ zu reagieren sind gescheitert.
Weclches self.connect( ...?...) muss ich dazu in __init__() von class MainWindow() einfügen?
Toll wäre, wenn Ihr in Eurer Antwort den beigefügten Code ergänzt. - Danke.
Schöne Grüße,
BeFu
P.S.: Wie kann ich die Anzeige des log-Widget verhindern, das nach Rechts-Klick auf self.listWidget erscheint?
EventSignalSlot.pyw:
Code: Alles auswählen
#!/bin/usr/env python3
# -*- coding: utf-8 -*-
#
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import loglistwidget # class of logListWidget in which
# specific event handlers are reimplemented
__DEBUG__= False # True for debugging
__version__ = "0.0.1"
MTIME= 5000 # time in ms for showing messages
# MainMindow is additional child from 'loglistwidget.LogListWidget'.
# Otherwise we won't be able to handle events (like mouse clicks) that
# are done in 'loglistwidget.LogListWidget'
class MainWindow(QMainWindow, loglistwidget.LogListWidget):
def __init__(self, parent= None):
super(MainWindow, self).__init__(parent)
self.dirty= False # True after change of file
self.filename= None
# log history of operations and show them in dock window
logDockWidget= QDockWidget("Log", self)
logDockWidget.setObjectName("LogDockWidget")
logDockWidget.setAllowedAreas(Qt.RightDockWidgetArea)
self.listWidget= loglistwidget.LogListWidget()
logDockWidget.setWidget(self.listWidget)
self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
# The calculated crc is shown in the application's status bar
self.crcLabel= QLabel() # Display Widget
self.crcLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
status= self.statusBar()
status.setSizeGripEnabled(False)
status.addPermanentWidget(self.crcLabel)
status.showMessage("Ready", MTIME)
# create application's actions with help method createAction
# File Menu Actions:
fileNewAction= self.createAction("&New ...", self.fileNew,
QKeySequence.New, None, "Load file")
fileOpenAction = self.createAction("&Open...", self.fileOpen,
QKeySequence.Open, None,
"Open file")
fileQuitAction= self.createAction("&Quit", self.close, "Ctrl+Q",
None, "Close the application")
# create reference of file menu in application's memu bar
self.fileMenu = self.menuBar().addMenu("&File")
# add created actions to application's file menue
self.fileMenuActions = (fileNewAction, fileOpenAction,
# fileSaveAction, fileSaveAsAction,
None,
# filePrintAction,
fileQuitAction)
self.connect(self.fileMenu, SIGNAL("aboutToShow()"),
self.updateFileMenu)
# set minimum size of MainWindow
self.setMinimumSize(600, 150)
if __DEBUG__ :
print("width= {}, heigth= {}".
format(self.listWidget.width(),
self.listWidget.height()))
self.setWindowTitle("EventSignalSlot v{}".format(__version__))
#### Frage:
# Welche Methode muss ich in LogListWidget() implementieren,
# damit ich das Signal (Event?) hier in MainWindow() auswerten
# kann, um z.B. die in LogLostWidget() erzeugte Maus - 'info'
# hier weiter verarbeiten zu können?
# Nach meinem Verständnis müsste hierzu ein SIGNAL (EVENT?)
# mit 'info' als Paramenter von LogListWidget() geliefert werden.
#
# Gemäß http://zetcode.com/tutorials/pyqt4/eventsandsignals/
# würde ich im hiesigen __init__() die SIGNAL-SLOT-Verbindug
# herstellen mit
# self.listWidget.mouseRelaseEvent.connect(self.showInfo)
# Das klappt nicht, da mouseReleaseEvent über keine Methode
# connect verfügt.
#
####
# drop mouse events that are taken in MainWindow.
# So they are not handled by the loglistwidget
def mouseReleaseEvent(self, event):
pass
def showListWidget(self):
print("Hallo")
#### Frage:
# Hier würde ich die SLOT-Methode implementieren, welche die von
# LotListWidget() gelieferte Maus - 'info' weiter verarbeitet,
# z.B. in einer MessageBox anzeigt, oder in einer Datei speichert ...
#
# def showInfo(self, info):
# QMessageBox.information(self, "listWidget Info",
# info, QMessageBox.Ok)
#
####
# helper method for creating available menu actions of our application
def createAction(self, text, slot= None, shortcut= None, icon= None,
tip= None, checkable= False, signal="triggered()"):
action= QAction(text, self)
if slot is not None:
self.connect(action, SIGNAL(signal), slot)
if shortcut is not None:
action.setShortcut(shortcut)
if icon is not None:
action.setIcon(QIcon(":/{}.png".format(icon)))
if tip is not None:
action.setToolTip(tip)
action.setStatusTip(tip)
if checkable:
action.setCheckable(True)
return(action)
# helper method for adding actions to appropriate menu in menu bar
def addActions(self, target, actions):
for action in actions:
if action is None:
target.addSeparator()
else:
target.addAction(action)
# method for controlling whether changes are made and should be stored
def okToContinue(self):
if self.dirty:
reply = QMessageBox.question(self,
"Checksum Calculator - Unsaved Changes",
"Save unsaved calculations?",
QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
if reply == QMessageBox.Cancel:
return False
elif reply == QMessageBox.Yes:
return self.fileSave()
return True
# method for displaying message in statusbar of MainWindow and
# list widget of log widget
def updateStatus(self, message):
self.statusBar().showMessage(message, MTIME)
self.listWidget.addItem(message)
def updateFileMenu(self):
self.fileMenu.clear() # clearing all action of 'File munu'
# add back original list of File menu actions except of 'flie quit'
self.addActions(self.fileMenu, self.fileMenuActions[:-1])
# Define own slot functions:of MainWindow
def fileNew(self):
if not self.okToContinue():
return
else:
self.updateStatus("Create new file not possible")
def fileOpen(self):
if not self.okToContinue():
return
else:
self.updateStatus("Open a file is not implemented yet")
return
# main #######################################################################
def main():
app = QApplication(sys.argv)
app.setApplicationName("EventSignalSlot")
form = MainWindow()
form.show()
app.exec_()
main()
Code: Alles auswählen
#!/bin/usr/env python3
# -*- coding: utf-8 -*-
#
# class of LogListWigdet with reimplemented specific event handlers
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class LogListWidget(QListWidget, QObject):
"""
'LogListWidget' is child of 'QListWidget' with reimplemented
event handlers.
Parameter:
----------
parent window
Reimplemented Event Handlers:
-----------------------------
mouseReleaseEvent: provides list with informations
after mouse button is released.
"""
def __init__(self, parent= None):
super(LogListWidget, self).__init__(parent)
self.mouseEventList=[] # list of data that are handled by the
# MainWindow of application
# PyQt implements also events that occur when we press a mouse boutten
# for example on a QtGui.QListWidget
#
# mouseReleaseEvent(self, QMouseEvent e)
# mousePressEvent(self, QMouseEvent e)
#
def mouseReleaseEvent(self, event):
"""
Reimplemented Event Handler:
SIGNAL oder EVENT?
------
list with the following elements:
- which mouse butten was released: 1 = Left Button, 2 = Right Button
- item at the position where mouse button was released
- x, v coordinates of position where mouse button was released
"""
self.mouseEventList.clear()
button= event.button()
if button == 1:
info=" Left Mouse Button was released"
if button == 2:
info= "Right Mouse Button was releaded"
# first element of list: 1= Left Button or 2= Right Button
self.mouseEventList.append(button)
#second element of list: x- and y-coordinate of mouse Position
mpos=(event.x(), event.y())
self.mouseEventList.append(mpos)
info+= " at x={}, y={}".format(mpos[0], mpos[1])
# select an item on which was clicked
item= self.itemAt(event.x(), event.y())
if item:
# third emelement of list: item that was clicked
self.mouseEventList.append(item)
info+= "; item: {}".format(item.text(), QMessageBox.Ok)
#### Frage:
# Der Inhalt von 'info' soll in 'MainWindow()' weiter
# bearbeitbar sein.
# 'MainWindow()' ist in 'eventsignalSlot.pyw' definiert
#
# QMessageBox hier auskommentiert, da sonst 'LogListWidget'
# hier verlassen wird.
#
# QMessageBox.information(self, "Mouse Info",
# info, QMessageBox.Ok)
####
if button ==2:
if QMessageBox.question(self, "Log",
"Do you really want to clear log list?",
QMessageBox.Ok, QMessageBox.No) == QMessageBox.Ok:
self.clear()
def getMouseEventList(self):
return(self.mouseEventList)
# Make events available by properties
mouseeventlist= property(getMouseEventList)
# main #######################################################################
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
logListWidget = LogListWidget()
logListWidget.show()
app.exec_()