[Python-de] Re: New overriden and generated QLineEdit class will

Hans-Peter Jansen <[email protected]>
Newsgroups gmane.comp.python.general.german
Message-ID <7578517.K5ixYmkLR7@xrated>
Am Samstag, 9. Oktober 2021, 19:54:15 CEST schrieb Mohsen Owzar:
> 
> Mein Problem ist ganz einfach. Jetzt wiederhole ich noch einmal Schritt für
> Schritt. Wenn ich mein Programm starte, muss in meinem Beispiel-Programm
> das Fenster mit dem Namen: «MainWindow namens Window1» erscheinen, das sich
> darauf nur ein Widget und zwar den frisierten QLineEdit oder besser gesagt
> die Klasse CustomLineEdit beherbergt. oder in meinem wirklichen Programm
> beim Start, zuerst das Haupt-Fenster (MainWindow
> https://imgur.com/I1Fdf2f)) erscheint und man erst dann beim Klick auf den
> Button «Setting» auf das Setting-Fenster (Settings-GUI:
> https://imgur.com/Ot1OF4J) gelangt. An dieser Stelle haben wir jetzt die
> gleiche Situation im Beispiel-Code und im wirklichen Code, mit einem
> Unterschied, dass im Beispiel-Code im «Window 1» kein LineEdit-Feld zu
> sehen ist, wenn man die «Zeile 12» im Code auskommentiert. Und wenn man die
> «Zeile 12» drin lässt, erscheint dieses Edit-Feld beim Start des
> Beispiel-Codes daraussen, was nicht korrekt ist. 

Eins nach dem anderen: talk with code

--8<--
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 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)

        central_widget = QWidget()
        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)
        central_widget.setLayout(hbox)
        self.setCentralWidget(central_widget)

        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()

    def closeEvent(self, event):
        self.keypad_window.close()
        super(MainWindow, self).closeEvent(event)

    @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.hide()

            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_())
-->8--

Entspricht dies nun dem gewünschten Verhalten?

Hier eine Erklärung:

QMainWindows sind speziell im Umgang mit Widgets:

https://doc.qt.io/qt-5/qmainwindow.html#qt-main-window-framework

Wenn Qt so was raus haut, dann sollte man dem auf den Grund gehen:
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "", which already has a layout

Du hättest einfach Dein CustomLineEdit als centralWidget setzen können.
Um Dir aber die Übernahme in Dein tatsächliches Projekt zu Erleichtern, 
habe ich jetzt das line edit widget in ein container widget verfrachtet, 
in dem Du wie gewohnt (mit eigenen Layouts) schalten und walten kannst.

Den __init__ code im CustomLineEdit brauchst Du nicht, da es Dir nur auf 
den event handler ankommt. 

Solltest Du eine __init__ Methode brauchen, würde ich mich immer am 
Original orientieren. Das würde dann so aussehen:

    def __init__(self, parent = None), oder 
    def __init__(self, contents = "", parent = None)

Eine dynamische Argumentliste, die das C++-Verhalten nachbildet, ist auch 
möglich, wird aber irgendwann kompliziert...

Ich will die parent Diskussion nicht zu sehr ausweiten. Im Prinzip machst 
Du dies schon richtig im Keypad_Window, da dies hier ein Kind vom main
window ist. Andererseits brauchst Du im main window sowieso eine andere 
close Implementierung, damit das Schließen des main window auch ein 
geöffnetes keypad widget schließt. 

Dann habe ich noch die show/hide Logik (hoffentlich) ein bisschen 
konsistenter gemacht. 

Die richtige Initialisierung des keypad Wertes beim wiederholten Aufruf
überlasse ich Dir als Hausaufgabe..

Ich hoffe, das bringt Dich erst mal weiter.

Rechnung folgt. ;-)

Cheers,
Pete


_______________________________________________
python-de Mailingliste -- [email protected]
Zur Abmeldung von dieser Mailingliste senden Sie eine Nachricht an [email protected]
https://mail.python.org/mailman3/lists/python-de.python.org/
Mitgliedsadresse: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.