Seite 1 von 1

PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 06:57
von MrRossi
Ich bin neu hier und werfe ein großes
"Hallo zusammen"
in die Runde.

Ich hoffe hier kann mir geholfen werden.
Also es geht um folgendes:
Ich benutze QT Designer und PySide um in einem OpenSource-Programm eine eigene
Erweiterung zu entwerfen.

Nun habe ich einen Dialog entworfen, der über einen Toolbar-Button aufgerufen wird.
In dem Dialog gibt es einen Push-Button, der den User veranlasst auf dem Bildschirm
Punkte abzugreifen.
Dabei ist der Dialog natürlich im Weg.
Ich habe dann ein Signal kreiert, das den Dialog ausschalten soll.
Das klappt auch.
Die Frage ist nun, wie bekomme ich den Dialog wieder zurück?

Das ist der Code:

Code: Alles auswählen

class Ui_RouteObject(object):
        
    def setupUi(self, Dialog):
        if Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.setEnabled(True)
....
self.PB_GetPoints.clicked.connect(self.GetPoints)
......
Bis hierher klappt alles.
Dann kommt ein weiters Signal, nachdem der User fertig ist am Bildschirm.

Code: Alles auswählen

if len(self.stack) == 2:
                self.view.removeEventCallback("SoMouseButtonEvent",self.callback)
                self.fc.fetchCoordinates.emit(self.stack)
Der Aufruf des Unterprogramms klappt, der Dialog bleibt allerdings versteckt.

Code: Alles auswählen

self.fc.fetchCoordinates.connect(Dialog.show)
self.fc.fetchCoordinates.connect(self.WritePos)
Kennt da jemand eine Lösung?
Es muss nicht Dialog.hide() sein, es könnte einfach auch der Dialog nur minimiert werden, zB.
Es soll einfach nur automatisch aus dem Weg und dann wieder kommen.

Vielen Dank.

Schöne Grüße
Christian

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 11:38
von __blackjack__
@MrRossi: Der letzte Schnippsel steht in der `setupUi()`-Methode? Falls nicht, wo kommt dann `Dialog` her? Werteden Fehlermeldungen/Ausnahmen auf der Konsole ausgegeben?

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 13:05
von MrRossi
__blackjack__ hat geschrieben: Donnerstag 26. März 2020, 11:38 @MrRossi: Der letzte Schnippsel steht in der `setupUi()`-Methode? Falls nicht, wo kommt dann `Dialog` her? Werteden Fehlermeldungen/Ausnahmen auf der Konsole ausgegeben?
Ja genau, in der setupUi(). Die ganze Sequenz sieht so aus:

Code: Alles auswählen

self.PB_GetPoints.clicked.connect(self.GetPoints)
self.fc=MakeSignal()
self.fc.fetchCoordinates.connect(Dialog.show)
self.fc.fetchCoordinates.connect(self.WritePos)
wobei

Code: Alles auswählen

class MakeSignal(QtCore.QObject):
	fetchCoordinates=QtCore.Signal(list)
Fehlermeldung kommt keine. Es passiert einfach nix.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 14:19
von __deets__
Ist Dialog eine Klasse? Wie soll ein slot auf einer Klasse eine Instanz beeinflussen? Das waere so, als ob du auf einen Bauplan eines Autos haust, um damit die Tuer eines danach gebauten Autos zu schliessen. Geht nicht.

Warum ist fetchCoordinates kein Signal des Objektes, das oben mit "self" zu sehen ist? Warum diese komische Indirektion mit MakeSignal?

Und zu guter letzt - was *soll* denn passieren? Da werden doch nur signal/slot-Verbindungen gemacht. Wer loest denn fetchCoordinates wann aus?

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 16:13
von MrRossi
Ich glaube da gibt`s einige Missverständnisse.

Dialog ist keine Klasse.
Das schaut so aus:

Code: Alles auswählen

class MakeSignal(QtCore.QObject):
    fetchCoordinates=QtCore.Signal(list)
    
class Ui_RouteObject(object):
        
    def setupUi(self, Dialog):
     	if Dialog.objectName():
        	Dialog.setObjectName(u"Dialog")
        Dialog.setEnabled(True)
	..............       
        self.tabWidget.setCurrentIndex(0)
                    
        self.PB_GetPoints.clicked.connect(self.GetPoints)
        self.PB_GetPoints.clicked.connect(Dialog.hide)
        self.fc=MakeSignal()
        self.fc.fetchCoordinates.connect(Dialog.show)
       # self.fc.fetchCoordinates.connect(self.WritePos)
        
        QMetaObject.connectSlotsByName(Dialog)
    # setupUi
    
    def GetPoints(self):
            self.view=ActiveDocument.ActiveView
            self.stack = []
            self.callback = self.view.addEventCallback("SoMouseButtonEvent",self.GetRObjectPos)
            
    def GetRObjectPos(self, info):
        down = (info["State"] == "DOWN")
        pos = info["Position"]
        if (down):
            pnt = self.view.getPoint(pos)
            self.stack.append(pnt)
            if len(self.stack) == 2:
                self.view.removeEventCallback("SoMouseButtonEvent",self.callback)
                self.fc.fetchCoordinates.emit(self.stack)
Und zu guter letzt - was *soll* denn passieren? Da werden doch nur signal/slot-Verbindungen gemacht. Wer loest denn fetchCoordinates wann aus?
Passieren soll, dass der mein Ui_RouteObject-Dialog wieder erscheint.
Mit Dialog.hide() ist der weg, und wenn das fetchCoordinates-Signal emittiert wird soll er wieder
erscheinen.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 16:20
von __deets__
Dialog sollte dann tunlichst dialog heissen, denn damit macht man in Python klar, dass etwas ein normaler Name ist. Dialog signalisiert hingegen "das hier ist eine Klasse". Und so wie ich mir das schon dachte: das signal sollte auf dem Ui_RouteObject direkt definiert werden. Es gibt gar keinen Grund, dass ueber diese Hilfsklasse zu machen.

Wenn das Signal ordnungsgemaess ausgeloest wird, dann sollte entweder der Dialog verschwinden, oder eigentlich eine Warnung auftreten. Was naemlich sein kann ist, dass hide nicht aufgerufen wird, weil das Signal ja noch eine payload hat, die hide gar nicht akzeptiert. Du kannst den Dialog in GetRObjectPos aber doch auch einfach direkt verstecken. Wozu da das Signal?

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 17:18
von MrRossi
Diese Extraklasse kommt daher, dass ich das überall in den Tutorials, die ich im www gefunden habe, so gemacht
wurde.
Mir gefällt diese extra Klasse auch nicht, aber ich weiß (noch nicht) wie ich das direkt in der Klasse machen soll/kann/muss.
Alles was ich bis jetzt probiert habe, hat nicht gefruchtet. Für Hilfe wäre ich dankbar.

Der Dialog verchwindet ja, das funktioniert. Sobald das Signal ausgelöst wird, ist er weg.
Die Frage ist, wie bekomme ich den wieder zurück.
Er soll ja nur für die Zeit der Benutzereingabe verschwinden.

Danke für die Unterstützung.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 17:45
von __deets__
Jede Klasse die Signale definieren will muss auch von QObject ableiten (direkt oder indirekt). Und du tust das nicht, dementsprechend geht das da nicht. Diese Tutorials die das so komisch machen wuerde ich im uebrigen gerne mal sehen.

Und zu deiner Frage: ein anderes Signal, das show aufruft.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Donnerstag 26. März 2020, 21:07
von MrRossi
Ich stehe erst am Anfang meiner Pyton-Zeit, also bitte ich um Nachsicht und Geduld.
__deets__ hat geschrieben: Donnerstag 26. März 2020, 17:45 Jede Klasse die Signale definieren will muss auch von QObject ableiten (direkt oder indirekt).
Das ist mir schon klar. Doch selbst, wenn ich meine Dialog-Klasse von QObject ableite, also

Code: Alles auswählen

class Ui_RouteObject(QtCore.QObject):
bekomme ich das nicht gebacken.
Und zu deiner Frage: ein anderes Signal, das show aufruft.
Ich habe ein zweites Signal gemacht, das auch sicher abgefeuert wird, weil das erste auch läuft, aber
der Dialog bleibt verschwunden.
War das so gemeint:

Code: Alles auswählen

self.fc.PosSelected.connect(Dialog.show)
self.fc.fetchCoordinates.connect(self.WritePos)
Dieses Signal läuft, self.fc.fetchCoordinates.connect(self.WritePos). Das kann ich kontrollieren
weil es einen Bildschirmausdruck gibt.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Montag 30. März 2020, 11:50
von MrRossi
Hallo nochmal

Weiß hier wirklich niemand Rat?

Grüße
Christian

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Montag 30. März 2020, 12:29
von __deets__
Nicht mit den hier gezeigten Versatzstuecken. Bau ein minimales Beispiel das dein Problem illustriert, dann kann man sich das anschauen. Ansonsten kann es nur bei einem allgemeinen 'show ist das Gegensueck von hide' bleiben, und so weit sind wir ja schon.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Mittwoch 1. April 2020, 15:55
von MrRossi
Habe es geschafft. Klappt jetzt so wie ich es haben wollte.
Ob`s elegant ist oder "die" richtige Lösung weiß ich nicht.

Code: Alles auswählen

class Ui_RouteObject(QtCore.QObject):
    def setupUi(self, Dialog):
        
        self.AllVecs=[]
        self.RObjectDialog=Dialog
        ....
        ....
       self.tabWidget.setCurrentIndex(0)
       self.PB_GetPoints.clicked.connect(self.GetSnapPoint)
       self.PB_GetPoints.clicked.connect(Dialog.hide)
       QMetaObject.connectSlotsByName(Dialog)
# setupUi
....
....
   def GetSnapPoint(self):
        if len(self.AllVecs) == 3:
            self.AllVecs=[]
        FreeCADGui.Snapper.getPoint(callback=self.ProcessPoint)        
                                                     
    def ProcessPoint(self,point,nil):
        .....
        if len(self.AllVecs) == 3:
            self.WritePos(self.AllVecs)
        else:
            self.GetSnapPoint()
        
    def WritePos(self, PosXYZ):
       .....
           self.RObjectDialog.show()
Danke für die Bemühungen.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Mittwoch 1. April 2020, 16:27
von __blackjack__
Ich würde sagen es ist falsch. Alleine schon in generiertem Code der einen Kommentar am Anfang hat(te) man solle daran nichts ändern ist schon grundfalsch. Genauso wie das Code generieren an sich falsch ist. Man lädt die ``*.ui``-Datei zur Laufzeit mit dem `PyQt5.uic`-Modul.

Und die ganzen Namen sind falsch geschrieben. Python wäre klein_mit_unterstrichen. Qt bringt halt das `camelCase` mit sich. Das ist an sich schon mal unschön, aber da dann noch eine dritte Namenskonvention einzuführen die gegen *beide* schon vorhandene geht, ist absolut unterirdisch.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Freitag 3. April 2020, 10:15
von MrRossi
Ich habe in einem vorigen Post bereits geschrieben, dass ich noch ziemlich am Anfang stehe mit dem Python-Programmieren und deshalb etwas um Nachsicht ersuche. Dass ich beim Rumprobieren und das ausprobieren und da probieren nicht auf Anhieb den perfekten Code hinknalle ist wohl verständlich. Es geht halt nur alles Stück für Stück.
Außerdem bin ich bei meinem Pythonbuch gerade erst dazu gekommen, wie die Schreibkonventionen bei Python aussehen.

Ich habe im Zuge meiner Entwicklung nun den ui-Dialog dynamisch geladen. Allerdings habe ich nun ein anderes Problem.
Und zwarfunzt ein Signal nicht mehr so wie vorher.

Code: Alles auswählen

class CreateRouteObject: 
    
    def __init__(self):

        self.all_vecs=[]

    def showform(self):
        path_to_ui = "C:/.../Resources/Forms/RouteObject.ui"
        
        self.form = FreeCADGui.PySideUic.loadUi(path_to_ui)
        self.form.show()
        self.form.pbGetPoints.pressed.connect(self.getSnapPoint)

    def getSnapPoint(self):
        FreeCAD.Console.PrintMessage("getSnapPoint entered")
        if len(self.all_vecs) == 3:
            self.all_vecs=[]
        FreeCADGui.Snapper.getPoint(callback=self.processPoint)        
     ......
getSnapPoint wird nicht mehr ausgeführt.
Auf dem Pushbutten pbGetPoints hängen 2 Signale.
Das eine direkt in Qt Designer gemacht, Dialog.hide() , das funktioniert.
Dieses zweite nicht.
Ich habe auch versucht, das zweite Signal direkt im Qt Designer zu machen. Allerdings kann ich dort nicht
self.getSnapPoint setzen sonder nur getSnapPoint.

Weiß da jemand was ich machen könnte?

Danke.

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Freitag 3. April 2020, 10:35
von __blackjack__
@MrRossi: Du verbindest jetzt aber auch ein anderes Signal als vorher‽

Re: PySide - Qdialog verstecken und wieder holen

Verfasst: Freitag 3. April 2020, 12:23
von MrRossi
Der PushButton ist der gleiche. Ich habe den nur umbenannt.
das pressed kommt daher, weil ich alles ausprobiert habe, "pressed", "clicked", usw.