auf bestehenden LibreOffice-Dialog zugreifen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

Hallo,

ich mache seit einiger Zeit meine ersten Gehversuche mit Python und nutze Python dabei in LibreOffice.


Wie kann ich mit Python durch alle Steuerelemente eines Dialogs in LibreOffice interieren, wenn der Dialog bereits per StarBasic gestartet ist?

Derzeitige Situation (StarBasic!):
Im Dialog ist eine Schaltfläche, die folgendes Makro startet:

Code: Alles auswählen

Sub StartSuche()
	Msgbox findControl(dia_eingabe, "txt_Mobil")
End Sub

Function findControl(dialog As Object, cn As String) 
	Dim ctl
	findControl = "Nichts gefunden"
	For Each ctl In dialog.Controls 
	      If ctl.Model.Name = cn Then
	           findControl = ctl.Text
	           Exit Function
	      End If
	Next ctl
End Function
Ich möchte nun die Funktion "findControl" in Python implementieren und von der Dialog-Schaltfläche dann die Python-Funktion so aufrufen:

Code: Alles auswählen

Sub StartSuche()
  oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
  g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
  oScript = g_MasterScriptProvider.getScript("vnd.sun.star.script:mysqlgetdata4.py$findControl?language=Python&location=user")
  RS_Python = oScript.invoke(Array(dia_eingabe, "txt_Mobil"), Array(), Array())

  Msgbox RS_Python	
End Sub
Um Unklarheiten auszuschliessen habe ich momentan die Datei "mysqlgetdata4.py" erstellt mit folgendem, rudimentären, Inhalt und der vorstehende Aufruf per Basic klappt und die Msgbox liefert "Test" zurück:

Code: Alles auswählen

def findControl(x, y):
    return "Test"


Die Frage ist wie ich die bestehende StarBasic Funktion "findControl" in Python implementiere.

Da das aber wahrscheinlich umfangreich ist, möchte ich lieber fragen: Wo finde ich Informationen zum gewünschten Dialog-Zugriff über das Dialog-Objekt, welches von StarBasic aus als Parameter an die Python-Funktion übergeben möchte und wso finde ich Informationen zur grundsätzlichen Handhabung von LibreOffice Dialogen und Steuerelementen in Python.
Eine Suche, hier im Forum, lieferte mir nur diesen Thread:
viewtopic.php?f=19&t=43994&hilit=LibreOffice+dialog

Eine Besonderheit meines Anliegens ist möglicherweise das mein Dialog nicht an ein LibreOffice-Dokument 'gebunden' ist, also kein direkter Bezug zum ThisComponent-Objekt existiert.




Gruß
Stephan
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Stephan_2021: Das ist überhaupt nicht umfangreich, das ist supersimpel. Das ist eine Schleife über die Controls mit einem ``if`` ob der Name dem gesuchten entspricht, und dann einem ``return`` falls ja. Man kann das StarBASIC im Grunde 1:1 übersetzen. Etwas kürzer weil man ``return`` verwenden, und nichts `Dim`\ensionieren braucht:

Code: Alles auswählen

def find_control(dialog, name):
    for control in dialog.Controls:
        if control.Model.Name == name:
            return control.Text
    return "Nichts gefunden"

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei ich die Schleife an der Stelle nicht verstehe, denn offenbar hat `dialog` eine Methode dafür: `getControl()`. Also in StarBASIC:

Code: Alles auswählen

Function findControl(dialog As Object, cn As String) 
  Dim ctl
  ctl = dialog.getControl(cn)
  If IsNull(ctl) Then
    findControl = "Nichts gefunden"
  Else
    findControl = ctl.Text
  End If
End Function
und in Python:

Code: Alles auswählen

def find_control(dialog, name):
    control = dialog.getControl(name)
    return control.Text if control else "Nichts gefunden"

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

Danke, das ist ja tatsächlich einfach.

Kannst Du bitte noch 2 Sätze darüber verlieren warum das zweite return nicht ausgeführt wird, wenn die If-Bedingung erfüllt war/ist? Vielleicht ist die Frage dumm, aber ich verstehe "return" bisher nur als Übergabe des Funktionswertes und nicht als Übergabe PLUS 'verlasse die Funktion'.

Was ich meine ist das Python anscheinend garkein Äquivalent zu "Exit Function" (Basic) benötigt.


Gruß
Stephan
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

Wobei ich die Schleife an der Stelle nicht verstehe, denn offenbar hat `dialog` eine Methode dafür: `getControl()`. Also in StarBASIC:
naja, in meinem Beispiel ist (aus Sicht der Funktion) "dialog" ein Parameter der das Dialog-Objekt beinhaltet und nicht nur ein 'sprechender' Platzhalter. Der Dialog selbst.

Der Dialog wurde/wird vorher in Basic (vekürzt so gestartet:

Code: Alles auswählen

'...
frm_eingabe = GlobalScope.DialogLibraries.AWT.dlgEingabeDB
dia_eingabe = CreateUnoDialog(frm_eingabe)
'...
dia_eingabe.execute()
Weil die Schaltfläche, die das andere Makro startet, das die Funktion aufruft, nur Teil des dialogs ist, könnte ich zwar, den Event der SChaltfläche auswerten um zum Dialog-Objekt zu kommen, simpler ist aber:

Code: Alles auswählen

Sub StartSuche()
	Msgbox findControl(dia_eingabe, "txt_Mobil")
End Sub

Also NICHT etwa:

Code: Alles auswählen

Sub StartSuche()
	Msgbox findControl(dialog, "txt_Mobil")
End Sub
denn "dialog" ist ja nicht das existierende Objekt.
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

könnte ich zwar, den Event der SChaltfläche auswerten um zum Dialog-Objekt zu kommen
also z.B.:

Code: Alles auswählen

Sub StartSuche(event)
	Msgbox findControl(event.Source.Context, "txt_Mobil")
End Sub
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

ach Gott ... meine Antwort geht an Deiner Frage komplett vorbei ...

Ja, natürlich geht es so, wie Du es schreibst. Der Grund für meine Schleife war, das ich Python eigentlich einsetzen will um durch ALLE Steuerelemente zu interieren (ohne Abbruchbedingung) weil das in Basic langsam ist. Aktuell brauchte ich das um mir alle Namen der Controls zu Dokumentationszwecken auszugeben und da kam mir die Idee doch auch mal nach Python zu fragen, denn ich werde wohl zukünftig zunehmend mehr in Python machen, allein schon wegen der Geschwindigkeit.

Mein Derzeitiges Projekt ist in wohl 98% in Starbasic und nur 2% in Python, nämlich bei den Datenbankzugriffen wo es auf Geschwindigkeit ankommt.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Stephan_2021: ``return`` bricht natürlich die Funktion ab. ``return`` heist auf Deutsch ja auch „kehre zurück“/„zurückkehren“. Und auch ``Return`` in BASIC verhält sich ja so, dass es eine Sprunganweisung ist, die zur Aufrufstelle hinter dem `Gosub` zurück kehrt. An der Stelle verdrehen wahrscheinlich Mitlesende die Augen, denn ich weiss, Du sagst Du hast keine Zeit Dich systematisch einzuarbeiten, aber die Grundlagen muss man schon irgendwie mal lernen. Also Funktionen, Schleifen, Grunddatentypen und deren Operationen. In der Python-Dokumentation gibt es ein Tutorial, das man IMHO mal durchgearbeitet haben sollte. Wenn man schon programmieren kann, dauert das auch nicht allzu lange. Man lernt da die Sprache kennen und kann schauen was sich gleich den bereits bekannten Sprachen verhält und wo es Unterschiede gibt.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Stephan_2021
User
Beiträge: 52
Registriert: Sonntag 11. Juli 2021, 09:43

``return`` bricht natürlich die Funktion ab. ``return`` heist auf Deutsch ja auch „kehre zurück“/„zurückkehren“. Und auch ``Return`` in BASIC verhält sich ja so, dass es eine Sprunganweisung ist, die zur Aufrufstelle hinter dem `Gosub` zurück kehrt.
Schön erklärt, so kann ich das problemlos verstehen.

Ich hätte nur nie alleine diesen Zusammenhang hergestellt, wohl weil ich nicht stillschweigend annahm das return in Python unbedingt das Gleiche tut wie in Basic und weil ich bisher return in Python nur ais der 'Perspektive' betrachtet habe das es mit Werte zurückgibt und nicht das es 'zurückkehrt', weil sich für mich der Übergang Basic-Python-Basic als etwas 'Abgegrenztes' darstellt, im Gegensatz zu Basic-Basic-Basic .... ich hatte da schlicht bisher den falschen Blick drauf.
aber die Grundlagen muss man schon irgendwie mal lernen
ich hatte sogar if-then in meinem Python Buch nachgesehen, bevor ich fragte, dort war aber kein Beispiel das ich als adäquat zu Deinem Code erkannte.

Ja, ich habe derzeitig tatsächlich kaum Zeit mich mit Grundlagen zu beschäftigen, ABER ich werde mir ab ca. Januar die Zeit nehmen, denn mich beeindruckt die Geschwindigkeit von Python beim Datenbankzugriff und so ist mein Interesse geweckt zukünftig mehr und mehr Basic durch Python zu ersetzen.

Gestehen muss ich aber das ich Python bisher nur mühevoll zu begreifen beginne, wohl weil ich nur diverse Basic-Dialekte kann und weder Java, noch C++ oder Ähnliches und also die reine Code-Struktur von Python für mein 'Basic-Auge' gewöhnungsbedürftig ist.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also bei ``if`` verstehe ich das nicht so ganz, weil das sieht doch in beiden Sprachen *sehr* ähnlich aus, insbesondere Strukturell ist das doch gleich:

Code: Alles auswählen

  If bedingung Then
    aktion
  ElseIf bedingung Then
    aktion
  ElseIf bedingung Then
    aktion
  Else
    aktion
  End If
und in Python:

Code: Alles auswählen

    if bedingung:
        aktion
    elif bedingung:
        aktion
    elif bedingung:
        aktion
    else:
        aktion
Anzahl der weiteren bedingten Zweige nach dem ``if`` und das ``else`` sind in beiden Sprachen jeweils optional.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Antworten