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