Hans-Peter Jansen schrieb am Freitag, 8. Oktober 2021 um 18:07:22 UTC+2:
Am Freitag, 8. Oktober 2021, 11:14:54 CEST schrieb Mohsen Owzar:
Hi all I have a question about a clickable QLineEdit. After searching some Hints, how to use QMouseEvent, I've written a program which is working almost good but with a small or perhaps big ugliness and that is: Below is the imgur link to the screenshots of my program after clicking the buttons in sequence: https://imgur.com/a/rfcP3qB Ich schätze, wir können an diesem Punkt in deutsch weitermachen.
Vielleicht solltest Du erst mal versuchen, dein Problem möglichst kurz zu formulieren. Ich kann hier nur eine Ablaufbeschreibung finden.
As you will see in the code blow, Ein whitespace damaged code ist ziemlich unbrauchbar, you know.. I override the QlineEdit widget and define a new class " CustomLineEdit " to generate a "clicked" signal, when the user pressed with mouse on this field. I use this "CustomLineEdit" class and place it on the MainWindow with the desired "layout". I couldn't figure out, why this widget is placed not in the MainWindow, but outside this window, as you can see in the top picture of the attached screenshots. Okay, hier sagst du, du willst dein widget im mainWindow platzieren.
Das macht man üblicherweise mit einer parent/child relationship. Da du aber in der Ableitung deiner Klasse diese *aller* Argumente beraubt hast, geht dir damit dieser Mechanismus (parent=..) verloren. Vielleicht nimmst Du mal dein __init__() ganz raus, dann solltest Du die default Signatur zurückbekommen, und kannst parent auch wieder setzen.
When I take the line 12 (self.show()) from the code, the generated class will not appear. The problem here is that at the beginning, the MainWindow with a LineEdit field should appear at the program start. Then, after clicking on this field, the keypad should come up outside the MainWindow. Hier widersprichst du dir. Aber ich glaube, ich habe dein Problem trotzdem richtig interpretiert.
Schau mal in die PyQt Beispiele, da solltest du alle Arten von subclassing, event handling, und so finden. Wichtig sind da noch die return codes aus den event handlern..
Gutes Gelingen.
Cheers, Pete
Could anyone see, where my mistake is? Thanks for any help. Mohsen Here is the code: &&&&&&&&&&&&&&&&&&&&&&&&&&& import sys from PyQt5.QtWidgets import (QApplication, QLineEdit, QPushButton, QMainWindow, QVBoxLayout, QHBoxLayout, QGridLayout, QWidget) from PyQt5.QtCore import pyqtSignal, pyqtSlot
class CustomLineEdit(QLineEdit): clicked = pyqtSignal()
def __init__(self): super().__init__()
self.show()
def mousePressEvent(self, QMouseEvent): self.clicked.emit()
class MainWindow(QMainWindow): def __init__( self, parent=None ): super().__init__(parent)
self.title = 'Window 1' self.left = 700 self.top = 300 self.width = 200 self.height = 200 self.initUI()
def initUI(self):
self.keypad_window = Keypad_Window(self)
hbox = QHBoxLayout()
self.cle = CustomLineEdit() self.cle.clicked.connect(self.show_keypad_window) self.cle.setFixedSize(220, 60) self.cle.setStyleSheet("color: red;" "background-color: yellow;" "font-family: Arial;" "font-weight: Bold;" "font-size: 30pt")
hbox.addWidget(self.cle) self.setLayout(hbox)
self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.show()
def show_keypad_window(self): self.keypad_window.show() self.hide()
def close(self): self.keypad_window.close() super(MainWindow, self).close()
@pyqtSlot(str) def update_label(self, txt): self.cle.setText(txt)
class Keypad_Window(QWidget): def __init__(self, parent=None): super().__init__() self.parent = parent
self.setGeometry(1200, 500, 230, 400)
vbox = QVBoxLayout() self.display = QLineEdit() self.display.setFixedSize(220, 60) self.display.setReadOnly(True) self.display.setStyleSheet("color: Blue; " "background-color: lightgreen;" "font-family: Arial;" "font-weight: Bold;" "font-size: 18pt") vbox.addWidget(self.display)
"""Create the buttons.""" self.buttons = {} self.gridlay = QGridLayout()
self.button_name = [['7', '8', '9'], ['4', '5', '6'], ['1', '2', '3'], ['C', '0', '>']]
self.command_name = [['7', '8', '9'], ['4', '5', '6'], ['1', '2', '3'], ['delete', '0', 'accept']]
for i in range(4): for j in range(3): text = self.button_name[i][j]
# keep a reference to the buttons self.buttons[i, j] = QPushButton() self.buttons[i, j].setText(text) self.buttons[i, j].setObjectName(text) self.buttons[i, j].setFixedSize(70, 70) if i == 3: if j == 0: self.buttons[i, j].setToolTip('Each click deletes\na digit to the left')
if j == 2: self.buttons[i, j].setToolTip('The whole displayed\nvalue will be taken!')
self.buttons[i, j].clicked.connect(self.call_button_fun(i, j, self.command_name))
# add to the GridLayout self.gridlay.addWidget(self.buttons[i, j], i, j) self.buttons[i, j].setStyleSheet("color: blue; " "background-color: cyan;" "font-family: Arial;" "font-weight: Bold;" "font-size: 20pt") vbox.addLayout(self.gridlay) self.setLayout(vbox)
def call_button_fun(self, i, j, command_name): def button_fun(): if command_name[i][j] == self.button_name[i][j]: displayed_text = self.display.text() self.new_text = displayed_text + self.button_name[i][j] self.display.setText(self.new_text)
if command_name[i][j] == 'accept': print('>-key pressed!') self.parent.cle.setText(self.new_text) self.close()
if command_name[i][j] == 'delete': print('C-key pressed!') self.display.setText('')
return button_fun
if __name__ == "__main__": app = QApplication(sys.argv) mainwindow = MainWindow()
# Exception abfangen, wenn sie nicht behandelt wurde sys._excepthook = sys.excepthook
def exception_hook(exctype, value, traceback): print(exctype, value, traceback) sys._excepthook(exctype, value, traceback) sys.exit(1)
sys.excepthook = exception_hook
sys.exit(app.exec_()) _______________________________________________ python-de Mailingliste -- pyth...@python.org Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an python-...@python.org https://mail.python.org/mailman3/lists/python-de.python.org/ Mitgliedsadresse: h...@urpla.net
Danke Hans-Peter für Deine Antwort. Ich wurde auch von Lars benachrichtigt, dass ich auf der falschen Seite (Deutsch) meine Frage in Englisch gestellt habe. Damit ich nicht noch eine Frage aufmache, werde ich unten meine Frage noch einmal auf Deutsch stellen. Aber zuerst zu Deinen Fragen:
Vielleicht solltest Du erst mal versuchen, dein Problem möglichst kurz zu formulieren. Ich kann hier nur eine Ablaufbeschreibung finden. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Ich dachte, dass ich das getan hätte und dass ich zu viel geschrieben habe. OK, wenn es so ist, ist nachfolgend eine kurze Beschreibung meines Problems: Ich muss eine GUI für eine Relais-Test-Ablauf-Steuerung schreiben, die in der Lage ist, durchs Betätigen einiger «Buttons» die Kontakte zu schliessen oder zu öffnen. Man kann die Wartezeit für die Schliess- / Öffnen-Zeit individuell für jeden Test einstellen. Dafür gibt es einen Button auf der Haupt-GUI (Settings), mit dessen Hilfe man auf das Settings-Fenster gelangt. Auf diesem Fenster befinden sich mehrere QLineEdit-Felder, die unter anderem für die einigen Zeit-Einstellungen zuständig sind.
Jetzt kommt mein Problem und Anliegen: Da am Ende, dieses Programms auf einem Raspberry Pi unter Linux laufen soll und nur ein Tablet mit Touchscreen und kein Keyboard vorhanden ist, habe ich um jedes Edit-Feld einen Button «Plus» oder «Minus» hinzugefügt, die den angezeigten Wert im Feld erhöhen oder erniedrigen. Wenn aber der gewünschte Wert sehr weit vom angezeigten Wert liegt, muss man mehrere Male klicken, um den Endwert zu erreichen. Damit es schneller geht, habe ich mir gedacht, dass ich mit einem Klick in dem Edit-Feld mit der Maus / Finger auf dem Tablet ein neues von mir geschriebenes Keypad-Objekt öffne, mit dessen Hilfe man den Endwert sofort eintippt und mit OK diesen Wert in das Edit-Feld übernimmt.
Ein whitespace damaged code ist ziemlich unbrauchbar, you know %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Das habe ich nicht verstanden, was Du damit meinst. Vielleicht weil das Wort «below» falsch «blow» geschrieben wurde oder vielleicht weil ich den Code nicht direkt nach dieser Zeile, sondern am Ende meiner Frage gebracht habe, war irgendwie nicht verständlich.
Dein Vorschlag mit dem Wegnehmen von «__init__()» %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% OK, das muss ich ausprobieren
Hier widersprichst du dir. Aber ich glaube, ich habe dein Problem trotzdem richtig interpretiert. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Ich glaube nicht. Damit es klar wird, werde ich den Link zu meinen eigentlichen GUIs-Screenshots auch hinzufügen, um es besser verstehen zu können.
Screenshot von MainWindow-GUI: https://imgur.com/I1Fdf2f Screenshot von Settings-GUI: https://imgur.com/Ot1OF4J Wenn ich auf dem Settings-Fenster (in meinem Beispiel Window 1 oder MainWindow) bin, wo die ganzen QLineEdit-Felder vorhanden sind, sind alle Felder sichtbar. Man kann ihre Werte entweder mit «+» oder «-» ändern oder mit einem Klick in das Feld das Keypad-Fenster (in meinem Beispiel Keypad_Window) öffnen. Aber dieses Fenster muss erst dann erscheinen, wenn auf das Feld eingeklickt wird. In meinem Beispiel-Code erscheint das «Window 1» (die original GUI Settings) ohne Edit-Feld
Schau mal in die PyQt Beispiele, da solltest du alle Arten von subclassing, event handling, und so finden. Wichtig sind da noch die return codes aus den event handlern %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Ja, ich habe die verschieden Versionen gesehen. Gerade deswegen bin ich verwirrt. Ich weiss nicht, wann ich die «__init__()» und «super()» Zeilen so leer lasse und wann bringe ich in «__init__» das Argument «parent=None» und «parent» in «Super().__init__(parent)». In verschiedenen Beispiele sind manchmal die eine Version in den anderen die andere Version oder sogar manchmal eine Kombination der beiden. Ich konnte daraus nicht schlau werden. Nirgendwo habe ich eine einfache klare Dokumentation bei meinen Google-Searches zu diesem Thema gefunden. Wie Du z. B. in Deinem Vorschlag erwähnt hast, warum soll ich den "init"-Part wegnehmen. Was hat das zur Folge, wenn es dadrin ist?
Daher meine Frage, ob jemand mir wirklich erklären kann, wann ich die Argument-Felder leer lasse und wann ich sie befüllen muss. Ich hoffe, dass mit oben gesagten / geschriebenen Du mein Problem besser verstehst und vielleicht mir eine Ausweg zeigst. Gruss Mohsen &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Und nun meine Frage in Deutsch wiederholt: Den Code werde ich nicht noch einmal hinzufügen, da er von der ersten englischen Frage enztnommen werden kann. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hallo zusammen Ich habe eine Frage zu einem anklickbaren QLineEdit. Nachdem ich einige Hinweise zur Verwendung von QMouseEvent gesucht habe, habe ich ein Programm geschrieben, das fast gut funktioniert, aber mit einer kleinen oder vielleicht großen Hässlichkeit und das ist: Unten ist der imgur-Link zu den Screenshots meines Programms, nachdem Sie nacheinander auf die Schaltflächen geklickt haben: https://imgur.com/a/rfcP3qB Wie Sie im angehängten Code unten sehen, überschreibe ich das QlineEdit-Widget und definiere eine neue Klasse " CustomLineEdit ", um ein "geklicktes" Signal zu erzeugen, wenn der Benutzer mit der Maus auf dieses Feld drückt. Ich benutze diese "CustomLineEdit" Klasse und platziere sie auf dem MainWindow mit dem gewünschten "Layout". Ich konnte nicht herausfinden, warum dieses Widget nicht im MainWindow, sondern außerhalb dieses Fensters platziert wird, wie Sie im oberen Bild der beigefügten Screenshots sehen können. Damit ich überhaupt dieses QLineEdit-Feld sehe, musste ich die Zeile 12 (self.show()) im Code hinzufügen. Wenn ich die Zeile 12 aus dem Code nehme, wird die generierte Klasse nicht angezeigt. Das Problem hierbei ist, dass am Anfang das MainWindow mit einem LineEdit-Feld beim Programmstart erscheinen sollte. Nachdem Sie auf dieses Feld geklickt haben, sollte die Tastatur außerhalb des MainWindow erscheinen. Könnte jemand sehen, wo mein Fehler liegt? Danke für jede Hilfe. Mohsen