... ich bekomms nicht auf die Reihe "Zugriff auf class"

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
GiJay
User
Beiträge: 36
Registriert: Freitag 5. März 2021, 14:40
Wohnort: Ratingen
Kontaktdaten:

Ok, Amazon hat mir für Samstag zwei Python-Bücher zugesagt, aber ich weiß noch nicht, ob dies die Lösung ist. Es scheint grundsätzlich in meinem Kopf etwas nicht angekommen zu sein. Ok, beschäftige mich das erste Mal mit "Objekten" und der Jüngste bin auch nicht mehr, aber so was von in den Seilen ...

Der Versuch: "Auflösung Monitor bestimmen"

Code: Alles auswählen

# -*- coding: utf-8 -*-myAnne.py

import sys
import winsound
#import ToolsIntern
#from WEinstellungen import *

from PyQt6.QtWidgets import QApplication, QMainWindow, QMdiArea, QMdiSubWindow, QMessageBox
from PyQt6.QtGui import QScreen

# Beginn Variablen -------------------------------------------------------------------------------------------
# error_msg_ini = False

# Ende Variablen ----------------------------------------------------------------------------------------------
   
class MyScreenSpace(QScreen):

    def __init__(self, myScreenBreite, myScreenHoehe):

        self.myScreenRect = MyScreen.availableVirtualGeometry().getRect()
        self.myScreenBreite = myScreenRect.x
        self.myScreenHoehe = myScreenRect.y


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)

        self.test1 = MyScreenSpace.myScreenBreite
        self.test2 = MyScreenSpace.myScreenHoehe

        msgBox = QMessageBox()
        msgBox.setWindowTitle("T E S T")
        msgBox.setText(test1 + test2)
        msgBox.exec()


    # MainFenster Einstellungen 
        self.setWindowTitle("Anne's kleines BueroTool - Vers. 0.1") 
        
        .....
        
ich habe ein Klasse "MyScreenSpace" gebildet, da ich diese Klasse später in meine "ToolKiste.py" kopieren will und per import einbinden möchte.

Die Klasse ist eine Instanz von QScreen.
Mit Self."xxxx" erzeuge ich im Konstrukor Instanzvariablen der gewünschten Werte.

Soweit korrekt?

In der Klasse "MainWindow" möchte ich nun auf die Instanzvariablen zugreifen. Dort wird aber die Klasse bzw. Instanz "MyScreenSpace" nicht erkannt.

Die Syntax bringt mich noch um ...

Merci!
__deets__
User
Beiträge: 14533
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du rufst den Konstruktor der super-Klasse nicht auf, du rufst irgendwelche nicht-existenten Namen auf (MyScreen gibt es nirgends), und vor allem versuchst du's auch immer mit Klassen, wo Instanzen dieser Klassen gefragt waeren.

Eine Klasse ist ein Blaupause. Auf der Blaupause eines Autos kannst du die Tuer nicht oeffnen. Erst, wenn du anhand der Blaupause ein Auto gebaut hast (oder 10), kannst du auf einem dieser Autos (der Instanz) die Tuer oeffnen.

MyScreenSpace.myScreenBreite ist aber wieder der Versuch, via Klasse an Dinge zu kommen, die auf einer Instanz stattfinden.

Die Klass MyScreenSpace ist konkret sinnlos, du kannst gleich mit QScreen arbeiten, von der Ableitung hast du nichts.
__deets__
User
Beiträge: 14533
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und nochmal ein Nachtrag, weil es diverse male in dem Quelltext oben vorkommt: Dinge, die du als dauerhafte Attribute in einer Instanz haben willst, muessen mit self. angesprochen werden.

Wenn du also self.text1 (ganz schlechter Name, und auch nicht wirklich notwendig, aber dazu gleich mehr) anlegst, und dich darauf spaeter beziehen willst, dann *musst* du self.text1 benutzen. Nicht nur text1. Das gleiche Muster findet sich andauernd, auch myScreenRect zB.

Namen mit my, oder Nummern dran, sind schlecht. Warum heisst der Text nicht "breite_text"? Oder "hoehe_text"? Statt durchzunummerieren?

Und fuer diese Namen gibt es auch gar keinen Grund, die an die Instanz zu binden. Den Text willst du ja nicht spaeter irgendwo wieder verwenden, sondern nur an der Stelle, wo du ihn zusammenbaust.

Zu guter Letzt: es sind auch keine Texte, sondern Zahlen. Das wird also nichts mit dem setText. Fuer sowas bieten sich f-Strings an:

Code: Alles auswählen

class MainWindow(QMainWindow):

        # App sollte uebergeben werden
    def __init__(self, app):
        super().__init__()

        self.mdi = QMdiArea()
        self.setCentralWidget(self.mdi)

        screen_size = app.primaryScreen().availableSize()
        msgBox = QMessageBox()
        msgBox.setWindowTitle("T E S T")
        msgBox.setText(f"{screen_size.width()} {screen_size.height()}")
Benutzeravatar
__blackjack__
User
Beiträge: 13099
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Eventuell würde es auch Sinn machen Klassen und Objektorientierung erst einmal separat (kennenzu)lernen, ohne Qt als ziemlich grosses umfangreiches Rahmenwerk.

Und gute Namen sind wichtig. Die Vorsilbe `my` ist eigentlich nie sinnvoll, weil die nichts aussagt was der Leser wissen müsste.

Die beiden Argumente von der `__init__()`-Methode werden nicht verwendet, damit sind die sinnlos.

Die Attribute `myScreenBreite` und `myScreenHoehe` wären inhaltlich falsch, weil die x, y-Koordinate von einem `QRect` nicht die Breite und Höhe beschreiben, sondern die Position der oberen, linken Ecke von dem Rechteck. Und das sind Methoden auf `QRect`, die müsste man auch aufrufen um an die Werte zu kommen.

Was man auch eher nicht machen würde ist das `QRect`-Objekt *und* dessen einzelnen Eigenschaften als Attribute zu definieren, denn das ist redundant und birgt die Gefahr, dass die Werte irgendwann mal auseinandergehen wenn man nicht immer daran denkt *beides* zu aktualisieren. Wenn man das `QRect` hat, braucht man Breite und Höhe nicht noch mal extra, und wenn man Breite und Höhe hat, braucht man dafür nicht zusätzlich noch das `QRect`-Objekt. Falls man eine Zugriffsebene weniger haben will, also `screen.width` statt `screen.rect.width()`, würde man das über ein `property()` lösen. Ich würde auch zu englischen Namen raten, sonst hat man am Ende eine undurchsichtige Mischung und muss immer erst überlegen ob es nun `breite` oder `width` heisst.

Die Kommentare für Beginn und Ende von Variablen kann man sich sparen, man sieht doch wo die Definitionen anfangen und Enden, auch ohne den Kommentar, und an *der* Stelle sollten sowieso keine Variablen definiert werden. Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Variablen haben dort nichts zu suchen, die sind immer lokal in Funktionen oder Methoden definiert.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
GiJay
User
Beiträge: 36
Registriert: Freitag 5. März 2021, 14:40
Wohnort: Ratingen
Kontaktdaten:

Hallo _blackjack_,

wenn auch spät: erst einmal vielen Dank für Deine Infos. Leider habe ich nicht mit Corinna, sondern mit Corona im Bett gelegen. NAch 3 TAgen war der Kopf schon wieder klarer und ich habe mir Deine vorsichtige Bemerkung "eventuell ... Sinn machen .... erst einmal" durch den Kopf gehen lassen. Du hast natürlich absolut Recht. Ich habe es mir zu Herzen genommen und über Superprof einen "Dozenten" gefunden, mit dem ich nun das Thema OOP vertiefe. Gerade haben wir mit "Vererbung" begonnen.
Leider, leider hat mein Dozent bislang nicht mit Qt gearbeitet. Er will sich zwar mal einen Überblick verschaffen, aber ob das funzt ..... ? Wir werden sehen.

Ja, Qt ist eine ziemlich großes Rahmenwerk und für den Anfänger zunächst nicht überschaubar. Ein Stück meiner über 60-jährigen Lebenserfahrung ist jedoch, dass man mit seiner Aufgabe wächst. Es gibt ein Ziel und Dinge, die zunächst "im Wege stehen", muss man lösen. Mit jedem Schrittchen kommt man dann etwas weiter. Ich hoffe dem kannst Du etwas abgewinnen.
Also "arbeite" ich parallel an meinem Code weiter. Diesen habe ich auch - Deinen Anmerkungen entsprechend - "gesäubert". Es gibt kein "My" und kein #Das ist eine Funktion :-)

Jetzt habe ich ein für mich besonderes Problem. Der Code läuft, es gibt keine Fehlermeldung, aber er tut nicht was er soll.
Mit den Menüpunkten "Setup, Kontakt und Objekt" kann ich mehrere Subfenster öffnen. Dies funktionierte zunächst. Nun war meine Gedanke, die Erzeugund der Subfenster in Klassen zu packen. Da ich z.B. mehrere Kontakte anzeigen will, wäre eine Klasse Kontakte ja nicht so verkehrt. Ich habe also versucht eine Klasse Setup zu coden. Der Code läuft durch, abe es wird kein SubFenster erzeugt/angezeigt.
Wo soll ich bitte suchen?

Code: Alles auswählen

 -*- coding: utf-8 -*-myAnne.py

import sys

sys.path.append('AnnesAppDir/')
import os.path
import winsound
from PyQt6.QtWidgets import QApplication, QMainWindow, QMdiArea, QMdiSubWindow, QLabel, QToolBar
from PyQt6.QtGui import QAction, QIcon
from PyQt6.QtCore import Qt

# Local application imports
from AnnesAppDir.OwnToolBox import DoErrorMsg, ReadIniFile, ReadNumberFromList

ini_file_name = 'AnnesAppDir/AnnesApp.ini'


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.main_space = QMdiArea()
        self.setCentralWidget(self.main_space)
        self.setWindowTitle("Anne's kleines BueroTool - Vers. 0.1")

        appMenuBar = self.menuBar()
        menuDatei = appMenuBar.addMenu("&Datei")
        window_setup = MakeSubwindowSetup
        self.menuDateiSetup = menuDatei.addAction("SetUp")
        self.menuDateiSetup.setShortcut("Ctrl+S")
        self.menuDateiSetup.setStatusTip("Programm-Einstellungen vornehmen")
        self.menuDateiSetup.triggered.connect(window_setup)
        menuDateiDrucken = menuDatei.addAction("Drucken")
        menuDateiDrucken.setEnabled(False)
        menuDatei.addSeparator()
        menuDateiEnde = menuDatei.addAction("Ende")
        menuDateiEnde.setShortcut("Ctrl+Q")
        menuDateiEnde.setStatusTip("Programm beenden")
        menuDateiEnde.triggered.connect(self.close)
        self.menuKontakte = appMenuBar.addAction("&Kontakte")
        self.menuKontakte.triggered.connect(self.new_subwindow)
        self.menuObjekte = appMenuBar.addAction("&Objekte")
        self.menuObjekte.triggered.connect(self.new_subwindow)
        self.menuDB = appMenuBar.addMenu("&db")
        self.menuDB.triggered.connect(self.new_subwindow)
        menuHilfe = appMenuBar.addMenu("&Hilfe")
        menuHilfeInfo = menuHilfe.addAction("Info")
        menuHilfeInfo.setShortcut("Ctrl+A")
        menuHilfeInfo.setStatusTip("Information für Anne")
        # menuHilfeInfo.triggered.connect(self.ShowMsgBoxHilfe)

        statusBar = self.statusBar()
        statusBar.showMessage("Hallo")

        tiledAct = QAction(QIcon("TB_1.png"), "Test", self)
        cascadeAct = QAction(QIcon("TB_2.png"), "Test", self)
        self.toolBar = QToolBar()
        self.addToolBar(Qt.ToolBarArea.LeftToolBarArea, self.toolBar)
        self.toolBar.addAction(tiledAct)
        self.toolBar.addAction(cascadeAct)
        tiledAct.triggered.connect(self.arrange_subwindows_tiled)
        cascadeAct.triggered.connect(self.arrange_subwindows_cascade)
        self.toolBar.addSeparator()

    def arrange_subwindows_tiled(self):
        self.main_space.tileSubWindows()

    def arrange_subwindows_cascade(self):
        self.main_space.cascadeSubWindows()

    #    def manager_subwindows(self):
    #        self.menuKontakte.setEnabled(False)
    #        self.menuObjekte.setEnabled(False)
    #        self.menuDB.setEnabled(False)
    #        subWindowList()
    #        if "setUp" dann erstelle Fenster
    #        MakeSubwindowSetup()

    def new_subwindow(self):
        sub = QMdiSubWindow()
        sub.setWindowTitle("subwindow")
        sub.setWidget(QLabel("SubWindow"))
        self.main_space.addSubWindow(sub)
        sub.show()

class MakeSubwindowSetup(MainWindow):
    def __init__(self):
        super().__init__()
        self.sub = QMdiSubWindow()
        self.sub.setWindowTitle("SetUp")
        self.sub.setWidget(QLabel("SetUp-Window"))
        self.main_space.addSubWindow(self.sub)
        self.sub.show()

class MakeSubwindowKontakt():
    pass

class MakeSubwindowObjekt():
    pass

class MakeSubwindowDB():
    pass


# --------------------------------------------------------------------------------------
app = QApplication(sys.argv)
prg = MainWindow()
prg.show()
# Start the event loop.
sys.exit(app.exec())
__deets__
User
Beiträge: 14533
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du schreibst einfach nur

Code: Alles auswählen

        window_setup = MakeSubwindowSetup
Das ist keine Erzeugung eines Objekts, das ist einfach nur das binden der Klasse MakeSubwindowSetup an den Namen window_setup. Da fehlen also mindestens mal die ().

Make ist auch ein ganz bescheidener Praefix fuer Klassen, weil "machen" etwas ist, das Funktionen und Methoden tun, wohingegen Klassen etwas "sind". Das waere so, als ob du die Blaupause fuer ein Auto "MachBMW" nennst. Du faehrst aber einen BMW, kein MachBMW.

sys.path.append('AnnesAppDir/') wird dir auch bald um die Ohren fliegen, weil es ein relativer Pfad ist. Das funktioniert nur hier und jetzt weil du zufaellig im richtigen Verzeichnis arbeitest, wenn das benutzt wird. Wird das jemals auf einem anderen Rechner installiert, oder auch nur irgendwie anders aufgerufen (nicht durch die IDE, sondern zB per Doppelklick oder sonstwas), dann ist es vorbei.

Darum fuer sowas immer Pfade aus der Variablen __file__ konstruieren. Am besten per pathlib. Wird hier auch permanent diskutiert. Gleiches gilt natuerlich auch fuer ini_file_name

Was dein Vorgehen angeht: es ist nachvollziehrbar, dass man an konkreten Aufgaben wachsen will. Ob es funktioniert, ist schwer zu sagen. Wenn man bestimmte Grundlagen nicht kennt, kann man bestimmte Dinge eben auch nicht verstehen, und dadurch nicht wirklich fuer sich nutzen. Darum eben solche Hinweise.
Benutzeravatar
__blackjack__
User
Beiträge: 13099
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@GiJay: Und wieder eine Runde Anmerkungen: `os.path` und `winsound` werden importiert, aber nicht verwendet. Wobei man statt `os.path` eher `pathlib` verwenden sollte in neuem Code.

Dann wieder Namen: `AnnesAppDir` ist ein Package und kein Verzeichnis. Ja, auf dem Datenträger ist das ein Verzeichnis, aber das muss nicht so sein, man kann Packages beispielsweise auch in Ziparchive packen und im Grunde auch den Importmechanismus beliebig erweitern das Packages von ganz wo anders kommen. Beispielsweise aus einer Datenbank oder über das Netz geladen werden. Aber selbst auf der Festplatte nennt man Verzeichnisse üblicherweise nicht `…Dir` weil diese Information ob das ein Verzeichnis, eine Datei (oder was noch spezielleres) ist, schon im Dateisystem selbst hinterlegt ist.

Namenskonvention für Packages ist auch klein_mit_unterstrichen. Und `ini_file_name` sollte als Konstante KOMPLETT_GROSS sein. Siehe auch: Style Guide for Python Code.Botz

Bei `OwnToolBox` ist das `Own` so ähnlich wie `My`. Kann es denn dort noch andere `ToolBox`-Packages oder Module geben? Und warum wären das nicht die Eigenen, denn das Package ist ja von Dir‽ Fremde Werkzeugkästen hätten da ja nichts zu suchen.

Die Namen die da importiert werden sind alle wie Klassen geschrieben, also ”Dinge” im weitesten Sinne, sind inhaltlich aber alles Tätigkeiten, also eigentlich Namen bei denen man Funktionen erwarten würde. Wenn es Funktionen sind, sollte die Gross-/Kleinschreibung entsprechend angepasst und Unterstriche eingefügt werden. Sollten es Klassen sein, dann sollten die Namen keine Tätigkeiten beschreiben sondern die ”Dinge” die von den Klassen modelliert werden.

Bei den beiden Fensteranordnungs-`Action`\s wird bei Auslösen jeweils eine Methode aufgerufen, die jeweils ihrerseits nur eine Methode mit den gleichen Argumenten (in diesem Fall keine) aufrufen. Den Zwischenschritt kann man sich sparen.

Wenn man die GUI von Hand schreibt, kann man ausnutzen, dass die Anbindung an die Qt-Bibliothek erlaubt beim Erstellen von Qt-Objekten sowohl Properties als auch Signalverbindungen als Schlüsselwortargumente direkt beim Erstellen der Objekte anzugeben. Im ersten Fall einfach den Propertynamen verwenden, im zweiten einfach nur den Signalnamen. Also beispielsweise:

Code: Alles auswählen

    button = QPushbutton("Activate me")
    button.setCheckable(True)
    button.clicked.connect(do_something)

    # =>
    
    button = QPushbutton("Activate me", checkable=True, clicked=do_something)
Ich habe hier gerade kein Qt auf dem Rechner darum kann ich nur sagen was ich im Quelltext sehe/vermute. Es wird recht sicher eine Fehlermeldung geben. Programme sollte man am besten immer ausserhalb einer IDE in einem Terminalfenster starten. Zum einen kann man dann sicher sein, dass die IDE keinen Einfluss hat und Ergebnisse verfälscht, zum anderen sieht man dort bei GUI-Programmen Fehlermeldungen die als Text ausgegeben werden.

`MakeSubwindowSetup` ist ein Hauptfenster, denn das erbt von `QMainWindow`. Was soll in diesem Fenster angezeigt werden? Ich vermute mal Du willst da gar kein Fenster also macht das erben von QMainWindow keinen Sinn. In der `__init__()` wird dann versucht ein `QMDISubWindow`-Objekt zu `self.main_space` hinzuzufügen — und spätestens *das* sollte dann zu eine `AttributeError` führen, der im Terminal ausgegeben wird, aber nicht zum Abbruch des Programms führt. `MakeSubwindowSetup` hat kein `main_space`-Attribut. Das hätte entweder `QMainWindow` schon haben müssen, dann hätte man das an der Stelle von dort geerbt, oder es hätte vorher in der `__init__()` angelegt werden müssen. Da die Methode ja kein *neues* `QMDIArea` erstellen soll, vermute ich mal, sondern das im bestehenden ersten Hauptfenster zum dortigen `QMDIArea` hinzugefügt werden soll, müsste man *das* an `__init__()` übergeben.

Aber auch das scheint mir nicht sinnvoll, denn es sollte wohl eher so sein, dass Du eine eigene Klasse von `QMDISubWindow` ableiten möchtest und ein Exemplar davon in Deiner Hauptfensterklasse erstellen und dort `self.main_space` hinzufügen möchtest.

Wobei ich an der Stelle mal anmerken möchte, dass ich persönlich von dem MDI-Konzept nicht so wirklich viel halte und zumindest versuchen würde an der Stelle die ”inneren” Fensterinhalte einfach in von `QWidget` abgeleitete Klassen zu stecken, so dass man sich entscheiden kann ob man das in einem echten Fenster oder in so einem MDI-Bereich anzuzeigen.

Die Abneigung gegen MDI kommt nicht nur daher, dass das Konzept eigentlich mal von Photoshop kam wo es im Original auf dem Mac tatsächlich normale Fenster gab und die Mac-Typische *eine* Menüleiste oben auf dem *Desktop*. Und als das nach Windows portiert wurde, haben die Entwickler überlegt wie sie das lösen, und haben dann ein Windowsfenster mit der einen Menüleiste genommen und die Fenster alle in dieses eine Fenster gesperrt.

Heutzutage, wo es nicht unüblich ist, dass man mehr als einen Monitor verwendet, ist das echt nervig, wenn man MDI-Anwedungen hat, die in *einem* Fenster auf *einem* Monitor leben müssen, und man nicht ”innere” Fenster davon mal eben auf den zweiten Monitor ziehen kann. Oder was ich auch öfter bei Mehrfensteranwendungen mache: das Hauptfenster auf allen Desktops anzeigen, und Unterfenster pro X (X=Kunde, Ticket, Bearbeitungsvorgang) aufmachen, so dass man zwar mehrere Sachen mit mehr als einem Fenster gleichzeitig in Bearbeitung haben kann, das aber nicht alles auf einmal auf dem Desktop zu sehen ist. Oder gar in *einem* Fenster auf nur einem Monitor.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
GiJay
User
Beiträge: 36
Registriert: Freitag 5. März 2021, 14:40
Wohnort: Ratingen
Kontaktdaten:

Erst einmal vielen Dank für Eure Bemerkungen und Tipps.
Ich habe bzw. werde davon noch vieles umsetzen. Aber alles auf einmal geht leider nicht. Ich weiß, dass die Path-Löung samt Verzeichnisnamen nicht taugt, aber ich habe erst vor 4 Wochen mit Python bzw. OOP und Qt angefangen. Ich werde dies alles mit der Zeit berichtigen und auch schreibweise und Namenswahl überarbeiten, aber ich stehe etwas unter Zeitdruck. Ich schreibe nicht mal eben einen Code runter, für mich ist das hier sehr, sehr mühsam, da noch vieles nachgeguckt und gelesen werden muss. Das Verständnis für OOP sitzt noch nicht und auch die Schreibweise ist nicht sattelfest ... vom Umfang der Sprache und Bibliotheken ganz abgesehen. Ich weiß, dass hier im gezeigten Code importe nicht genutz werden. Dies passiert, wenn ich Dinge wie "ini-File lesen" oder eigene Fehlermeldungen aus dem Code herausnehme um nicht einen aufgeblasenen Code hier zu veröffentlichen. Natürlich wisst Ihr nichts davon und könnt nur das beurteieln, was ich da so poste. Ich bitte dies nachzusehen.
Ich habe mich heute über Stunden mit einem Problem beschäftigt, was für Euch sehr wahrscheinlich gar nicht nachvollziehbar ist.

Code: Alles auswählen

 
 top = QFrame()
 top.setFrameShape(QFrame.Box)


Dies ergibt bei mir eine Fehlermeldung. "QFrame kennt das Attribut Box nicht. Lese ich in der Qt-Dokumentation finde ich das :
enum Shape { NoFrame, Box, Panel, StyledPanel, HLine, …, WinPanel }
QFrame habe ich natürlich von QWidgets import. Irgendwas übersehe ich, begreife ich (noch) nicht ... da geht echt viel Zeit bei drauf. Ich lasse, dass dann manchmal liegen und mach erst einma an einer anderen Stelle weiter. Vielleicht kommt mir ja morgen die Erleuchtung

Ich brauche noch eine Idee: Ich habe mein MainWindow und mache darin diverse Subwindows auf. Ich wollte mit subWindowList() eine Liste führen, die mir angibt, welche Fenster geöffnet sind. Das tut sie auch, da ich die Anzahl der offenen Fenster daraus mit "len()" ableiten kann. Wenn ich nun ein Fenster durch click aufs Kreuzchen schließe, erhalte ich auch die korrekte Anzahl der offenen Fenseter, aber die Liste weiß nicht, welches Fenster geschlossen wurde. Ich brauche also ein "Erkennungsmerkmal" welches Fenster aus meiner Liste geschlossen wurde. Wird ein verwendbarer "Wert" in subWindowList mitgeführt? Kann ich diesen Wert ermitteln? Wie setzt ich so etwas um?

Schönen Abend noch ...
Benutzeravatar
__blackjack__
User
Beiträge: 13099
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ist in der Tat komisch, denn `Box` sollte auf `QFrame` definiert sein:

Code: Alles auswählen

In [85]: PyQt5.QtWidgets.QFrame.Box
Out[85]: 1
`subWindowList()` liefert die angezeigten Fenster. Wie sollten dort nicht mehr angezeigte mitgeführt werden? Falls Du von QMdiSubWindow ableitest, könntest Du dort ein Signal implementieren das ausgelöst wird, wenn das Close-Event dort behandelt wird, oder Du könntest von ”aussen” über `QObject.installEventFilter()` an diese Ereignisse heran kommen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
xpyWolf
User
Beiträge: 6
Registriert: Donnerstag 29. Dezember 2022, 17:25

Hi,
Ich habe Deinen Code mal runter geladen und getestet.
Da ja nichts gemacht wird hat mein python3.8 mit pyqt5 auch nichts gemeckert.
Was ich allerdings gesehen habe, ist der Unterschied, wenn ich ein MainWindow oeffne:

Code: Alles auswählen

class costCalcUi(QMainWindow):
   def __init__(self):
      QMainWindow.__init__(self)

Kann das einen Unterschied machen?
Zuletzt geändert von xpyWolf am Donnerstag 29. Dezember 2022, 18:21, insgesamt 1-mal geändert.
Benutzeravatar
xpyWolf
User
Beiträge: 6
Registriert: Donnerstag 29. Dezember 2022, 17:25

Hallo,
Also um eine Instanz von "MyScreenSpace" zu erzeugen, solltest Du in der Klasse: class MainWindow(QMainWindow)
folgendermaßen vorgehen:

Code: Alles auswählen

   mss = MyScreenSpace(intBreite, intHoehe)
   # int bedeutet integer Wert
   self.test1 = mss.myScreenBreite()
   self.test2 = mss.myScreenHoehe()
somit hast du eine Instanz mit dem Namen "mss" aus Deiner Blaupause "MyScreenSpace" gebildet.
Und nur mit der Instanz "mss" kannst Du weiterarbeiten. Ist eigentlich wichtig.

Ich editier das jetzt zum dritten mal.
Du MUSST eine Instanz von MyScreenSpace erzeugen. Sonst wird es nichts.
Und das machst Du mit

Code: Alles auswählen

mss = MyScreenSpace(intBreite, intHoehe)
Leider :(
Zuletzt geändert von xpyWolf am Donnerstag 29. Dezember 2022, 18:19, insgesamt 2-mal geändert.
Benutzeravatar
xpyWolf
User
Beiträge: 6
Registriert: Donnerstag 29. Dezember 2022, 17:25

Hallo ,
hab mal was ausprobiert mit dem Screen, weil es mich auch interessierte.
Bin bis zum primaryScreen gekommen. Mehr musst Du dann mal selber finden.
Also dass hat bei mit mit Qt5 funktioniert, ohne irgendwelche Klassendefinition:

Code: Alles auswählen

# -*- coding: utf-8 -*-screenSize.py 

import sys
# import winsound
#import ToolsIntern
#from WEinstellungen import *

from PyQt5.QtWidgets import QApplication, QMainWindow, QMdiArea, QMdiSubWindow, QMessageBox
from PyQt5.QtGui import QScreen


if __name__ == "__main__":
   app=QApplication(sys.argv) # application initialisieren
   screen = app.primaryScreen()
   print(screen.geometry().width())
   print(screen.geometry().height())
   
und die Augabe war dann korrekt als:

Code: Alles auswählen

wolf@wolfXku:~/wdata/projekte/python3/tests$ python3 screenSize.py 
1600
900
getestet auf KUbuntu 20 LTS auf einem Dell Latitude E5430

Bis die Tage
Antworten