GUI für LibreOffice Calc

Plattformunabhängige GUIs mit wxWidgets.
Antworten
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Guten Abend im Forum,

ich habe ein Problem mit einer kleinen GUI, bestehend aus Fenster Texteingabefeld und Button. Wenn die Schaltfläche gedrückt wird, dann wird der Inhalt des Textfeldes in eine Tabellenzelle geschrieben. Das funktioniert auch. Die GUI wurde mit dem aktuellen wxFormbuilder 3.8.1 erstellt. Ich Teste unter Windows 10 und Ubuntu Bionic Beaver.

Folgende Probleme: Unter Windows erscheint der Textboxinhalt erst nach dem Schließen des Fensterchens. LibreOffice stürzt nicht ab.

Unter Ubuntu erscheint zwar der Textfeldinhalt unmittelbar nach drücken des Button in der Zelle aber LibreOffice stürzt komplett ab und startet im Wiederherstellungsmodus. Es passier auch bei Nutzung der durch den wxFormBuilder erzeugten XRC-Datei.

Kennt jemand von Euch das Problem?

Viele Grüße und erstmal gute Nacht

Zarathustra
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zarathustra: Wie sind denn das Programm und Calc verbandelt? Also wie fügst Du von einem wxWidgets-Programm aus etwas in eine Tabellenzeile in Calc ein?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Guten Morgen __blackjack__

ich hole mir als globale Variablen zunächst das Dokument

Code: Alles auswählen

oDoc = XSCRIPTCONTEXT.getDocument() 
und dann das Sheet mit: oSheet = oDoc.CurrentController.ActiveSheet

Die Funktion des Button enthält einfach nur zwei Zeilen:

Code: Alles auswählen

oCell = oSheet.getCellRangeByName("A1")

Code: Alles auswählen

oCell.String = self.txtCtrl_1.GetValue()
Hinsichtlich des Absturz unter Ubuntu muss ich mich korrigieren. Dieser passiert nicht beim drücken des Button sondern beim Schließen der GUI über das Kreuz am Fenster.

Ich vermute man muss sich eine Funktion zum "Fenster schließen" erzeugen die etwas enthält, was die Verbindung zu oDoc und oSheet wieder kappt.

Hier das vollständige Script:

Code: Alles auswählen

import wx
import LibreOfficeWX as LOWX

oDoc = XSCRIPTCONTEXT.getDocument()
oSheet = oDoc.CurrentController.ActiveSheet

class Eingaben(LOWX.Hauptfenster):
	def __init__(self, parent):
		LOWX.Hauptfenster.__init__(self, parent)
		
	def btn_1_clicked(self, event):
		oCell = oSheet.getCellRangeByName("A1")
		oCell.String = self.txtCtrl_1.GetValue()
		return None
		
def Aufruf(*args):
	app = wx.App(False)
	frame = Eingaben(None)
	frame.Show(True)
	app.MainLoop()

if __name__ == '__main__':
	Aufruf(False)
Gerade habe ich mal obiges Script aufgerufen OHNE die Verbindungen zu Office. Also alle Zeilen mit oDoc, oSheet, oCell auskommentiert und LibreOffice stürzt immer noch ab. Liegt es an der Funktion "Aufruf" ?

Viele Grüße und Danke

Zarathustra
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zarathustra: Wo kommt denn `XSCRIPTCONTEXT` her? Kann es sein das Du das aus einem in die Tabellenkalkulation integriertem Python-Interpreter startest? Kann/Darf man da einfach so `wx` verwenden?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

@__blackjack__: Ja klar! Ich starte das aus LibreOffice mitgelieferte Python. Zumindest definitiv unter Windows. Dort habe ich zunächst pip installiert und mir dann noch zusätzlich geholt was ich brauche. wxPython, numpy, scipy, matplotlib, pandas.

Bei Linux muß man den libreoffice-scriptprovider-python installieren, sonst kann man unter "Extras"-->"Makros"-->"Makros Verwalten"-->"Python..." nicht aufrufen.

Ich weis nicht ob man das darf. Ich hab's getan. In einigen der Beispiele die ich im Netz zum Thema "LibreOffice Calc mit Python" gefunden habe, war der Weg so beschrieben. Aber halt immer nur "normale" Python Funktionen, ohne GUI. Auf die Idee mit GUI bin ich gekommen. Ich denke dass es so gehen müsste. Tut's halt nicht. :-(
Ich dachte sowas hätte hier auch schon mal jemand probiert.
Ich vermute, dass man eine Funktion während der Close-Funktion der GUI ausführen muss, die die Verbindung zwischen dem Python-Interpreter und Calc wieder kappt.

Auf'm Mac sieht's noch erbärmlicher aus. Da bekomme ich in das LibreOffice-Python noch nichtmal wxPython und numpy installiert. Einzig das Update von pip selbst hat funktioniert.

Es gibt wohl irgendwelche Wege, wie man anstelle des LibreOffice-Python ein bereits auf dem System vorhandenes Python nutzen kann (unter Linux ist das glaube ich so, durch denlibreoffice-scriptprovider-python), aber das erscheint mir auf's Erste zu kompliziert.

Viele Grüße

und einen schönen Sonntag

Zarathustra
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Guten Abend,

__blackjack__ hast wohl Recht. Man darf es scheinbar nicht. Ich kann nämlich auch alles auskommentieren was "Libre Office angeht" und beim Schließen stürzt der Salat ab. Hhm eigentlich Schade. Ich dachte hier läge ein riesengroßer Vorteil von LO gegenüber MSO. Da muß ich sagen, geht der Punkt an MSO, denn hier funktioniert die Eingabe aus einer wxPython-GUI in eine Tabellenzelle via "xlwings" hervorragend. Bisher nur auf dem Mac getestet aber dann wird's unter Windows wohl auch klappen.

Problematik zwar nicht gelöst, denke aber das Thema kann zu den Akten.

Schönen Abend noch

Zarathustra
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zarathustra: Ich würde halt erst mal schauen was das Programm selbst bietet. Man kann ja soweit ich weiss auch mit LibreOffice selbst Dialoge etc. erstellen. Mit StarBASIC ging das jedenfalls wenn ich mich recht erinnere. Hätte auch den Vorteil das man unter den verschiedenen Betriebssystemen nicht noch extra eine GUI-Bibliothek installieren muss.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

zarathustra hat geschrieben: Montag 22. Oktober 2018, 20:22 Man darf es scheinbar nicht. Ich kann nämlich auch alles auskommentieren was "Libre Office angeht" und beim Schließen stürzt der Salat ab. Hhm eigentlich Schade. Ich dachte hier läge ein riesengroßer Vorteil von LO gegenüber MSO. Da muß ich sagen, geht der Punkt an MSO, denn hier funktioniert die Eingabe aus einer wxPython-GUI in eine Tabellenzelle via "xlwings" hervorragend. Bisher nur auf dem Mac getestet aber dann wird's unter Windows wohl auch klappen.
Man kann GUIs nicht so einfach mischen. Aber LO hat doch sein eigenes GUI-Toolkit, warum benutzt du das denn nicht?
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo __deets__

wenn Du Tk meinst, das funktionierte nicht. Das startete erst gar nicht, sondern stieg mit diversen Fehlermeldungen gleich beim Aufruf aus. die genauen Meldungen habe ich nicht mehr auf dem Schirm. Irgendwas beim Aufruf einer pythonscript.py-Datei. Keine Ahnung. Auf Windows war es meine ich nicht möglich Tk nach zu installieren.

Beim LO-Forum hatte sich auch schon jemand an Tk versucht, fand aber, meine ich, auch kein glückliches Ende.

xlwings mit Excel und wx klappt, bis auf die Tatsache, dass bei Mojave's dunklem Hintergrund der Schaltflächentext nicht vernünftig lesbar ist. Auch wenn man definiert, dass der Text des Button unterstrichen sein soll, wird das nicht zwingend übernommen. Obwohl man speichert und den Code neu generiert. Ich vermute ein Bug im wxFormbuilder aber weiß es nicht wirklich.

Dessen flatpak-Variante war unter Linux nicht wirklich gut benutzbar. Man hat überhaupt kein Fenster auf der Designeroberfläche gesehen und bei dunklem Hintergrund (BlackMate) war der Objektinspektor oder Eigenschaftseditor oder wie sich das auch immer nennt nicht wirklich lesbar. Weiße Schrift auf hellgelbem Untergrund. Ging gar nicht.

Übrigens hat(te) Firefox ein ähnliches Problem mit der Lesezeichenliste. Aber das nur am Rande.

Tk-GUI ging nicht und eine mit glade gebastelte GUI zeigte ähnliche Zicken wie wx.

Ich denke die Macher von LO wollen nicht, dass Python mit GUI betrieben wird. Eine Möglichkeit fällt mir gerade ein, wäre einen Basic-Dialog zu bauen und hier dann über die Schaltfläche via Basic-Befehl das Pythonscript zu starten. Sofern das geht. Bei xlwings ist das RunPython.

Das mit den Dialogen in LO funzt auch nicht so wie bei VBA, von wegen Formular, Buttons und Textbox drauf, Doppelklick auf den Button und man landet in der "Button-Click-Prozedur"...

Viele Grüße

Zarathustra
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zarathustra: Wir meinen nicht Tk sondern das GUI-Toolkit von LibreOffice. Kann man das von Python aus nicht benutzen? Ich hätte vermutet das man mit Python das gleiche machen kann wie mit BASIC.

Das hat weniger etwas damit zu tun was die Macher von LO wollen, sondern mehr damit das man mehr oder weniger grundsätzlich nicht mehrere GUI-Rahmenwerke mischen kann, weil *die* das nicht vorsehen. Das macht in der Regel ja auch gar keinen Sinn.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo __deets__, hallo __blackJack__

jetzt verstehe ich was ihr meint. Diese VCL Library. Da fand ich keine Hinweise bezüglich Python. Basic Dialoge. Ich meine da auch über etwas gestolpert zu sein, wie man per Basic-Befehl ein Python-Script starten kann.

Ich dachte einfach man kann Tk, wxPython, Gtk oder Qt oder oder... einfach so verwenden.

Viele Grüße

Zarathustra
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein. Entweder benutzt du PyUNO Remote als Server. Dann kannst du tun was du willst. Oder du versuchst Skripte IN LO laufen zu lassen (also gleicher Prozess). Dann geht das nicht. Bei mir geht es aber unter Ubuntu schon so nicht. Schmiert einfach ab.....
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo,

hat jemand mal makros für calligra sheets ausprobiert? Hier scheitere ich schon daran, dass ich kein Modul names "KSpread" oder "Kross" importieren kann. KSpread scheint durch Kross ersetzt zu sein, oder in Kombination zu funktionieren. Jedenfalls finde ich keine aktuelleren Beispiele.

Hat hier jemand Erfahrung damit? Auch in Punkto GUI mit wxPython?

Viele Grüße

Zarathustra
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo und guten Abend,

Nachdem ich auf Elementary OS umgestiegen bin und aktuelles Libreoffice installiert habe, habe ich mich mal wieder dem Thema gewidmet und herausgefunden wie es gehen kann/könnte.

Unter Libreoffice einen Dialog angelegt. Dieser besteht aus einer Form mit einem TextField und einer Schaltfläche. Er hat den Namen Dialog1.
In der Basic-Umgebung habe ich im "Objektinspektor" der Schaltfläche den Namen "Btn1" und dem Textfeld den Namen "TextFeld1" gegeben.

Mit dem Dateimanager zunächst im Home-Ordner die versteckten Dateien anzeigen lassen und zu .config/libreoffice/4/user durchhangeln und wenn noch nicht vorhanden die Ordner Scripts/python ergänzen. Sieht dann so aus: /home/benutzername/.config/libreoffice/4/user/Scripts/python Hier habe ich dann das Pythonscript gespeichert.
Script:

Code: Alles auswählen

 # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import uno, unohelper
from com.sun.star.awt import XActionListener
import msgbox as util

def BeispielDialog(*args):   #<------In der Klammer muß *args stehen sonst funktioniert es nicht
    global dialog, calc
    calc = XSCRIPTCONTEXT.getDocument()
    ctx = XSCRIPTCONTEXT.getComponentContext()
    smgr = ctx.getServiceManager()
    DialogProvider = smgr.createInstanceWithContext("com.sun.star.awt.DialogProvider", ctx)
    dialog = DialogProvider.createDialog("vnd.sun.star.script:Standard.Dialog1?location=application") #<------Hier wird der Dialog mit Namen Dialog1 angesprochen
    btn = dialog.getControl("Btn1") #<-------An der Stelle wird die Schaltfläche geholt. Ihr hatte ich ja den Namen "Btn1" gegeben 
    btn.addActionListener(MeineAction()) #<-----Der Schaltfläche wird ein ActionListener zugewiesen
    dialog.execute()
    dialog.dispose()

class MeineAction(unohelper.Base, XActionListener): #<-----Der ActionListener
    def __init__(self):
        pass
 
    def disposing(self, ev):
        pass
 
    def actionPerformed(self, ev):
        TF1 = dialog.getControl("TextFeld1") #<--------"Kontaktaufnahme" mit dem Textfeld des Dialoges
        Zelle = calc.Sheets[0]['A1']
        Zelle.setString(TF1.getText()) #<----Hier wird einfach nur der Textfeldinhalt in die Zelle "A1" geschrieben
        MsgBox(TF1.getText()) #<-----Und hier nochmal Textausgabe in einer MessageBox ausgebeben.

def MsgBox(txt: str):
    mb = util.MsgBox(uno.getComponentContext())
    mb.addButton("Ok")
    mb.show(txt, 0, "Python")
Mit "Extras--->Makros---->Makros ausführen" wählt man dann "BeispielDialog" und der Dialog erscheint. Drücken auf die Schaltfläche schreibt dann den Text in die Zelle A1.
Man kann sich auch eine Schaltfäche auf das Tabellenblatt legen und diesem das Makro zuweisen (mache ich immer zum Testen).

Allerdings hat der Dialog den Focus. Man kommt nicht an das Tabellenblatt heran. Erst wenn der Dialog wieder geschlossen ist. Aber das wird sich vielleicht auch noch lösen lassen.

Was ich auch noch nicht im Griff habe sind Matplotlib-Fenster. Danach stürzte LO auch immer ab. Weil Matplotlib ja, wenn man nix anderes vorgibt, Tk-Fenster verwendet. Und Tk-GUI sich mit LO nicht verträgt.

Viele Grüße

Zarathustra
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann wäre multiprocessing eine Möglichkeit. Damit kannst du Daten in einen anderen Prozess schaufeln.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Ohne genau zu wissen was multiprocessing ist bzw. wie's funktioniert (hab' gestern Abend mal danach gesucht -stehe da noch am Anfang) wäre das denn dann nicht auch was um eine "LO-Fremde-GUI" laufen zu lassen?

Man bräuchte dann vermutlich drei Prozesse. Einen für die GUI, einen für den Zugriff von der GUI zu LO, und einen für die Ausgabe (z.B. von LO in einen Matplot)

Liege ich da mit meiner dunklen Vorahnung in etwa richtig oder funzt das gar nicht?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du eine GUI baust, dann kann die ja matplotlib unterstuetzen. Das Problem sind ZWEI GUI-Frameworks in einem Prozess. Das geht halt (wie diverse male schon argsprochen) eher nicht. Darum reichen zwei Prozesse.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo __deets__

ich habe mir die einfachen Beispiele für Multiprocessing mal angesehen und versucht mir nützlich zu machen. Meine Vorgehensweise ist vermutlich völlig falsch. Ich habe einfach eine weitere Funktion geschaffen die als Starter dienen soll:

Code: Alles auswählen

def StarterBeispielDialog(*args): 
und da den Prozessaufruf integriert.

Code: Alles auswählen

def StarterBeispielDialog(*args):
    p = Process(target=BeispielDialog)
    p.start()
    p.join()
Das führt dazu, dass sich LO aufhängt und spätestens nach dem zweiten Aufhängen muß ich das Betriebssystem neu starten, weil bei LO nix mehr geht.

Könntest Du mir zeigen wie man den Dialogaufruf in einen Prozeß einbindet? Nur wenn's nicht zu viel Tipparbeit (<5 Zeilen Code) für Dich ist. Vielen Dank dafür.

Viele Grüße

Zarathustra
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hm. Ich denke eher das ich da was nicht bedacht habe, nämlich das multiprocessing so spät zum Zuge kommt (weil LO es erst aufruft via Makro), dass da das Kind schon im Brunnen ist.

Ich denke nochmal ein bisschen nach. Statt multiprocessing muss es wohl eher subprocess werden, aber wie die dann geschickt miteinander kommunizieren, muss ich noch rausfinden.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Vielleicht wäre https://pypi.org/project/execnet/ eine Möglichkeit.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten