keyPressEvent und [Space]

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Hallo,

Zunächst mein Code:

Code: Alles auswählen

import serial
import sys
from PyQt4 import QtCore, QtGui

class Gui(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        
        self.rs = serial.Serial('COM3', 9600)
        
        self.TextArea = QtGui.QTextEdit(self)
        self.TextArea.setReadOnly(True)
        
        self.setCentralWidget(self.TextArea)
        
        
    def keyPressEvent(self, event):
        key = event.text()
        print 'key pressed:', key
        self.TextArea.setText(self.TextArea.toPlainText() + event.text())


        
app = QtGui.QApplication(sys.argv)


muh = Gui()
muh.show()


app.exec_()
Mein problem ist dieses:
Egal welche ich Taste ich drücke wird die Funktion `keyPressEvent` aufgerufen. Bisher habe ich nur eine Ausnahme gefunden: Die Leertaste.
Da passiert einfach garnichts.
Jetzt möchte ich aber, das auch dabei was passiert...

Wie bekomme ich das hin?

lg,
...


[EDIT] Verwende python2.5 aus Python(x,y)2.5 auf Windows2000
lunar

Wenn Du Tastatureingaben an das Textfeld abfangen möchtest, dann überschreibe die Ereignisbehandlung im Textfeld selber.

Ich weiß nicht, was Dein Ziel ist, aber Du musst bedenken, dass Du neben Buchstaben auch andere Tasten wie die Pfeiltasten abfängst, welche Du natürlich auch korrekt implementieren musst. Vielleicht ist es daher sinnvoller, das "textChanged()"-Signal abzufangen.

Den Text aktualisierst Du auf höchst ineffiziente Art und Weise. Statt jedes Mal den kompletten Text zu kopieren, zu konkatenieren und wieder zu setzen, ist es wesentlich besser, den Textcursor an das Ende zu verschieden und den Text anschließend einfach einzufügen.

Davon abgesehen benötigst Du offenbar kein vollständiges QTextEdit mit seinen Formatierungsmöglichkeiten. Insofern ist QPlainTextEdit wohl die sinnvollere Wahl.

Korrigiert sieht das dann so aus: http://paste.pocoo.org/show/188318

Übrigens: Gibt es einen besonderen Grund, warum Du Windows 2000(!) und Python 2.5 verwendest? Windows 2000 ist veraltet, die Unterstützung durch Microsoft läuft bald aus oder ist bereits ausgelaufen. Statt Python 2.5 empfiehlt sich zumindest Python 2.6.
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

Hab ich bei mir so gelöst:

Code: Alles auswählen

class KeyEventEater(QObject):
    def __init__(self, parent = None):
        super(KeyEventEater, self).__init__(parent)
        
    def eventFilter(self, obj, event):
        if event.type() == QEvent.KeyPress:
            if event.key() == Qt.Key_Space:
                print "SPACE"
            return True
        else:
            return QObject.eventFilter(self, obj, event)

 
in der Klasse wo die Events gefangen werden sollen:

Code: Alles auswählen

eventEater = KeyEventEater(self)
self.installEventFilter(eventEater)
Sollte auch tun

Gruß
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Win2k ist halt hier auf diesem Uralt-Rechner installiert...
Ein 14-Jähriger Rechner läuft halt auch irgendwann mal aus, aber bis dahin muss man ihn zusammen halten.

Mein Laptop läuft mit Ubuntu 9.10 und Python 2.4 - 2.6 / 3.x

Warum ich die abfangen will...
Gute Frage...
Ich möchte den jeweils getippten Buchstaben per pySerial an ein Modem schicken, und überprüfen, ob das Signal angenommen wird - wenn ja, dann soll er geschrieben werden... oder so...

Du kennst vieleicht noch das HyperTerminal.
Wenn ich da etwas eingeben will, das nicht mit at beginnt, ignoriert er alle Tasteneingaben, bis at gedrückt wurde...
Und sowas will ich irgendwie auch Realisieren.
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

lunar hat geschrieben: Donnerstag 11. März 2010, 13:07

Übrigens: Gibt es einen besonderen Grund, warum Du Windows 2000(!) und Python 2.5 verwendest? Windows 2000 ist veraltet, die Unterstützung durch Microsoft läuft bald aus oder ist bereits ausgelaufen. Statt Python 2.5 empfiehlt sich zumindest Python 2.6.
Ich nutze Windows 10 und Python3
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

es geht einfach! Hier der richtige Link der Hilft:
https://stackoverflow.com/questions/118 ... -enter-key

Meine Lösung:

Code: Alles auswählen

vButtonAnwender = QPushButton("Hallo &Anwender",self)
        vButtonAnwender.setGeometry(20, 45, 130, 30)
        vButtonAnwender.setAccessibleName("Der Anwender wird begrüßt")
        vButtonAnwender.setToolTip("Der Anwender wird begrüßt")
        vButtonAnwender.clicked.connect(HalloAnwender)
        vButtonAnwender.setDefault(True)
        vButtonAnwender.show()
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PythonMarlem: Das `setGeometry()` sieht ”gefährlich” aus, das sollte da eher nicht stehen, sondern der Button sollte in einem Layout stecken.

Die Namensgebung sollte auch mehr den Python-Konventionen entsprechen. Ja, PyQt hält sich da nicht dran weil Qt ein C++-Rahmenwerk ist und anderen Konventionen folgt, aber weder bei Python noch bei Qt ist `HalloAnwender` richtig geschrieben sofern das nicht tatsächlich eine Klasse ist.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
PythonMarlem
User
Beiträge: 90
Registriert: Dienstag 19. Mai 2020, 19:17
Wohnort: Dußlingen
Kontaktdaten:

__blackjack__ hat geschrieben: Samstag 30. Mai 2020, 19:18 @PythonMarlem: Das `setGeometry()` sieht ”gefährlich” aus, das sollte da eher nicht stehen, sondern der Button sollte in einem Layout stecken.
Der Dozent auf Udemy hat das immer so gemacht und hat auch mir auf Nachfrage versichert, dass das plattformunabhängig ist.
Ich habe wenig Erfahrung mit Layouts! Muss ich erst noch lernen.
Die Namensgebung sollte auch mehr den Python-Konventionen entsprechen.
Ja, wenn mein Programm das macht was es soll, kümmere ich mich darum.
Ist das der richtige Link: https://www.python.org/dev/peps/pep-0008/
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PythonMarlem: `setGeometry()` hat nicht mal etwas mit der Plattform zu tun, das ist auch auf immer ein und der selben Plattform ein Problem. Es sind absolute Angaben in Pixeln und bei dem heutigen Zoo von Displaygrössen und -auflösungen geht so etwas einfach nicht mehr. Bis in die 90er hinein ist man noch damit durchgekommen einfach anzunehmen das alle eine Displaygrösse haben bei der 96 DPI verwendet wird oder dann mindestens die Einstellungen des Systems so gemacht haben, dass das funktioniert, aber die Zeiten sind lange vorbei.

Gerade wo Du Dich doch um Accessibility kümmerst: Stell Dir einfach jemand sehbehinderten vor, der in den Betriebssystemeinstellungen die allgemeine Schriftgrösse hoch einstellt. Irgendwann wird "Hallo Anwender" nicht mehr in die 130×30 Pixel passen die Du dafür bereit stellst. Darum verwendet man Layouts. Dann bestimmt der Button seine Grösse selbst, aufgrund des Textes und der Schriftgrösse. Und die letztendliche Position bestimmt sich aus dem Layout und den anderen Widgets darin. Wenn mehrere Buttons nebeneinander layoutet werden, dann sorgt das Layout dafür, dass alle nebeneinander stehen, egal welche Displayauflösung und Schriftgrösse das System verwendet, und egal welcher Text im Button steht. Ohne das man irgendeine Angabe in Pixeln machen muss, die man selbst bei einer bekannten Auflösug und Schriftgrösse irgendwie schätzen oder experimentell ermitteln muss für die Grösse und ausrechnen für die Position.

Änderungen gehen dann auch leichter. Wenn man beispielsweise Buttons mit einem HBoxLayout nebeneinander anordnet, kann man am Anfang einfach einen weiteren Button einfügen in dem man den vor den anderen zum Layout hinzufügt. Man braucht nicht aufwändig manuell die Positionen für alles rechts vom Button neu berechnen und im Programm eintragen.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Antworten