PyQT Anfänger | Hilfe zu SIGNAL/SLOT

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Dorsai!
User
Beiträge: 7
Registriert: Mittwoch 4. August 2010, 21:12

Ich versuche mich gerade in PyQT einzuarbeiten.
Folgendes Script hab ich geschrieben um mich ein bisschen mit SIGNAL/SLOTs in QT vertraut zu machen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from mainwindow import Ui_MainWindow

class window(QtGui.QMainWindow):
  def __init__(self):
    QtGui.QMainWindow.__init__(self)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)
    self.connect(self.ui.newentry, QtCore.SIGNAL("pressed()"), QtCore.SLOT(self.message()))
    
  def message(self):
    print "I am a Button!"

if __name__ == "__main__":
    #cout = consoleoutput()
    app = QtGui.QApplication(sys.argv)
    window = window()
    window.show()
    sys.exit(app.exec_())
Was es machen soll:
Wenn ich auf den Button klicke soll eine Nachricht in die Konsole gegeben werden.

Was es macht:
Es gibt die Nachricht einmal beim starten ab, aber dafür nicht wenn ich auf den Button klicke.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Natuerlich, `self.message` wird ausgefuehrt, du uebergibst da nicht das Methodenobjekt.

Lass die Klammern weg.
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Hallo,
versuch mal folgendes:

Code: Alles auswählen

# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
from mainwindow import Ui_MainWindow

class window(QtGui.QMainWindow):
  def __init__(self):
    QtGui.QMainWindow.__init__(self)
    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)
    self.connect(self.ui.newentry, QtCore.SIGNAL("pressed()"), self.message)
    # oder mit der neuen API
    self.newentry.pressed.connect(self.message)
    
  def message(self):
    print "I am a Button!"

if __name__ == "__main__":
    #cout = consoleoutput()
    app = QtGui.QApplication(sys.argv)
    window = window()
    window.show()
    sys.exit(app.exec_())
Kann es leider nicht testen, da mir deine mainwindow.py fehlt, sollte aber so gehen.

Gruß
Whitie

Edit: Zu spät ;)
lunar

@Dorsai!: Woher hast Du diesen Quelltext? Die Verwendung von SLOT() in dieser Form ist einfach nur vollkommen falsch.

Vergiss, dass es SLOT() gibt, und übergebe immer Methodenobjekte:

Code: Alles auswählen

self.connect(self.ui.newentry, QtCore.SIGNAL('pressed()'), self.message)
Wenn Du Qt 4.5 oder neuer verwendest, ist es ferner empfehlenswert, gleich die neue API zu lernen, und "QtCore.SIGNAL()" auch zu vergessen:

Code: Alles auswählen

self.ui.newentry.pressed.connect(self.message)
Nebenbei bemerkt solltest Du auch auf pyuic verzichten und stattdessen die GUI mit "uic.loadUi()" dynamisch laden. Das hat aber keine Eile, schau erst mal, dass Du Signale und Slots verstehst. Dir muss klar sein, warum Dein Quelltext das fehlerhafte Verhalten gezeigt hat.
Dorsai!
User
Beiträge: 7
Registriert: Mittwoch 4. August 2010, 21:12

Natürlich!

Mir war nicht klar wie SLOT funktioniert. Ich kann ihm einfach eine objekt.methode übergeben.

Ich dachte ich sage ihme führe DAS aus wenn signal auftritt. Das ist natürlich falsch.

Danke auch für die anderen Anregungen. Jetzt komme ich endlich weiter.

Danke besonders an lunar mit dem Tipp bezüglich der neuen API.
lunar

@dorsai!: SLOT() funktioniert auch nicht, wenn Du ein Methoden-Objekt übergibst. SLOT funktioniert nur und ausschließlich mit Zeichenketten, die die Signatur eines C++-Slots beschreiben. Nochmals: Vergiss, dass es SLOT() überhaupt gibt.
Dorsai!
User
Beiträge: 7
Registriert: Mittwoch 4. August 2010, 21:12

Ja, mir gefällt dein Vorschlag ohnehin besser, da ich qt-4.6.3 habe.
mzh
User
Beiträge: 295
Registriert: Dienstag 3. März 2009, 15:27
Wohnort: ZH

lunar hat geschrieben:@dorsai!: SLOT() funktioniert auch nicht, wenn Du ein Methoden-Objekt übergibst. SLOT funktioniert nur und ausschließlich mit Zeichenketten, die die Signatur eines C++-Slots beschreiben. Nochmals: Vergiss, dass es SLOT() überhaupt gibt.
Also ich lese gerade 'Rapid Gui Programming with PyQt' von Mark Summerfield. SLOT() wird da sehr häufig gebraucht... Ich bin noch nicht durch das ganze Buch, aber das ist also etwas von dem du abraten würdest?
[url=http://www.proandkon.com]proandkon.com[/url]
BlackJack

@mzh: Wenn ich mich nicht verzählt habe, sind in dem Buch in 110 `connect()`-Aufrufen in Quelltextbeispielen 19 bei denen der Empfänger mit `SLOT()` angegeben wird. Wenn es benötigt wird, kann man es ja verwenden, aber in den allermeisten Fällen ist der Empfänger wohl eine selbstgeschriebene Python-Funktion.
lunar

@mzh: Ja, ich würde davon abraten. Falls möglich, ist es sowieso empfehlenswert, die neue API zu nutzen, in der SLOT() gar nicht mehr vorkommt. SLOT() ist aber auch bei der alten API nie nötig, sondern bei C++-Slots nur geringfügig effizienter. Das ist aber im Allgemeinen vollkommen egal, somit ist im Sinne der Konsistenz und der Lesbarkeit eine Methodenreferenz zu bevorzugen.
Antworten