mousePressEvent eines QLabels

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Riebers
User
Beiträge: 9
Registriert: Sonntag 18. Juni 2017, 18:52

Hallo Elite,

ich möchte gerne mittels Qlabel eine Liste erstellen. Dabei wird zuerst ein Fenster geöffnet und mit dem Drücken eines Qlabel ein neues Fenster. Das zweite Fenster soll mit Hilfe eines mousePressEvent geöffnet werden. Bei dem neuen Fenster sollen dann aus vier Farben, dargestellt mit farbigen Qlabels, gewählt werden. Mein Problem ist, dass das mousePressEvent gar nicht berücksichtigt wird. Es wird sofort die List ausgegeben. Kann mir jemand weiterhelfen warum das so ist?!

CODE Hauptfenster:

Code: Alles auswählen

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
import Test2

class Window1(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = uic.loadUi("Window1.ui",self)
        
        
        self.window2 = Test2.Window2()
        
        self.lbl0.mousePressEvent = self.kombination()						# Bei drücken des Labels (lbl0) soll sich das zweite Fenster öffnen
        
        self.show()
    def kombination(self):
        self.window2.show()
        self.kombination = list()
        self.window2.lbl_r.mousePressEvent = self.kombination.append("red")	# Bei drücken des Labels im zweiten Fenster (lbl_r) soll "red" der list 
        print("Kombination: {}".format(self.kombination))					# hinzugefügt werden
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = Window1()
    sys.exit(app.exec())
CODE zweites Fenster:

Code: Alles auswählen

from PyQt5 import uic

from PyQt5.QtWidgets import QWidget

class Window2(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = uic.loadUi("Window2.ui",self)
    
Die Gui's habe ich mit dem Qt designer erstellt...
Es wird direkt "Kombination: ['red']" ausgegeben. Falls ich etwas vergessen habe bzw. etwas undeutlich ist bitte bescheid geben^^.

Grüße
Riebers
Zuletzt geändert von Anonymous am Mittwoch 12. Juli 2017, 18:06, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da ist manches quer.

self.kombination ist eine Methode. Wenn du die als Ereignisbehandlung benutzen willst, darfst du sie *NICHT* aufrufen. Sondern musst sie als Wert uebergeben. Kleines Beispiel (ohne Qt) zur Illustration:

Code: Alles auswählen

class Foo(object):

    def kombination(self):
          print("kombination")

class Bar(object):

      def __init__(self, event):
            self._even = event
 
       def trigger(self):
              self._event() # JETZT wird's aufgerufen

foo = Foo()
bar = Bar(foo.kombination) # NICHT aufrufen, sondern die gebundene Methode uebergeben
bar.trigger()
Dann ueberschreibst du self.kombination mit einer Liste, was man so nicht tun sollte, sondern einen neuen Namen dafuer benutzen. Und zu guter letzt rufst du auch da schon wieder etwas direkt auf, statt es als aufrufbares Objekt (callable in Python-Lingo) an mousePressEvent zu uebergeben.

Eine Moeglichkeit das zu tun ist ein lamba zu benutzen:

Code: Alles auswählen

self.window2.lbl_r.mousePressEvent = lambda: self.kombination.append("red")   # dadurch wird's ein callable, und nicht sofort aufgerufen.
Riebers
User
Beiträge: 9
Registriert: Sonntag 18. Juni 2017, 18:52

Danke deets für die Verbesserungen, jedoch verstehe ich nicht ganz wie ich das umsetzen soll. Ich habe mein code wie folgt verändert, bekomme aber immer einen "RecursionError: maximum recursion depth exceeded while calling a Python object".

Code: Alles auswählen

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5 import uic

     
class Window1(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = uic.loadUi("Master1.ui",self)
        
        self.win1 = Window1()
        self.win2 = Window2(self.win1.kombination)
           
        self.lbl11.mousePressEvent = self.win2()              # Bei drücken des Labels soll sich das zweite Fenster öffnen
           
        self.show()
    def kombination(self):
        
        print("Juhu es klappt!")                  
           
        

class Window2(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = uic.loadUi("Master2.ui",self)
        
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    example = Window1()
    sys.exit(app.exec())
Kannst du mir da weiterhelfen?
Zuletzt geändert von Anonymous am Mittwoch 19. Juli 2017, 11:02, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast ja nun nix von dem was ich geschrieben habe in irgendeiner Art umgesetzt. Das mousePressEvent ist *schon wieder* kein Callback. Zum einen, weil du mein Beispiel offensichtlich nicht wirklich angeschaut hast, zum zweiten, weil du versuchst, ein Window aufzurufen, was dann auffallen wuerde, wenn du die Klammern (wie ich ja schon schrieb) weglaesst, oder ein lambda: davor packst.

Und da ich deine ganzen UI-Dateien nicht habe, kann ich ja nun auch nicht wirklich etwas aus dem Code machen.

Ich schlage vor, du versuchst einfach mal, ein simples Minimalbeispiel on UI-Files zu bauen, um dich mit der Mechanik der Callbacks vertraut zu machen. Das hat dann auch eine Chance hier verbessert zu werden.

Ich bin auch immer noch nicht davon ueberzeugt, dass dein mousePressEvent Ansatz richtig ist. Normalerweise verbindet man sich mit clicked-Signalen. Aber da mag ich falsch liegen.
BlackJack

@Riebers: Vollzieh doch einfach mal nach was da passiert. Schritt für Schritt. Notiere Dir die Aufrufe auf einem Blatt Papier die da nach und nach passieren, dann solltest Du sehr schnell sehen wo diese Endlosrekursion liegt.

Zur Frage des `mousePressEvents`: Warum verwendest Du denn ein Label um eine Aktion auszulösen? Das erwartet man als Benutzer ja nicht wirklich, sondern eine Schaltfläche oder einen Link den man anklicken kann. Letzteren kann man auf einem `QLabel` anzeigen lassen, dann würde man das `linkActivated`-Signal verbinden.
Antworten