🙏 Helfen Sie jetzt mit, unser LibreOffice Forum zu erhalten! 🙏
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱
🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀
>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗
Python Listenfeld
Python Listenfeld
Moin,
aus Interesse bin ich dabei,eine kleine Anwendung mit Libreoffice CALC in python zu programmieren. Python ist mir vom Raspi bekannt. TKInter ist Neuland. Worum geht es?
Im Sheet Daten im beiliegenden ods File werden Arbeitszeiten gespeichert. Ich möchte mit einem Dialog bei Bedarf aus diesen Daten für je einen Monat die Zeiten herrausfiltern, Diese herrausgefilterten Daten sollen später als PDF ausgedruckt und gespeichert werden. Ich weis, es geht einfacher, ich möchte aber mal sehen, wie soetwas mit python realisiert werden kann.
Das Problem ist, das ich die in den Listboxen selectierten Daten nicht in die Function _setFilter() bekomme, um sie dort weiter zu verarbeiten. In der Function werden mir die Daten in einer messagebox angezeigt. Ich habe einenScreenshot beigefügt. Mit dem Inhalt kann ich leider nichts abfangen. Ich habe in den letzten Tagen keine Anwort auf die Frage finden können. Kann mir bitte jemand weiterhelfen? Ist das ein Libreoffice oder ein Python Problem?
Es grüßt
Gerd
aus Interesse bin ich dabei,eine kleine Anwendung mit Libreoffice CALC in python zu programmieren. Python ist mir vom Raspi bekannt. TKInter ist Neuland. Worum geht es?
Im Sheet Daten im beiliegenden ods File werden Arbeitszeiten gespeichert. Ich möchte mit einem Dialog bei Bedarf aus diesen Daten für je einen Monat die Zeiten herrausfiltern, Diese herrausgefilterten Daten sollen später als PDF ausgedruckt und gespeichert werden. Ich weis, es geht einfacher, ich möchte aber mal sehen, wie soetwas mit python realisiert werden kann.
Das Problem ist, das ich die in den Listboxen selectierten Daten nicht in die Function _setFilter() bekomme, um sie dort weiter zu verarbeiten. In der Function werden mir die Daten in einer messagebox angezeigt. Ich habe einenScreenshot beigefügt. Mit dem Inhalt kann ich leider nichts abfangen. Ich habe in den letzten Tagen keine Anwort auf die Frage finden können. Kann mir bitte jemand weiterhelfen? Ist das ein Libreoffice oder ein Python Problem?
Es grüßt
Gerd
- Dateianhänge
-
- Zeitzettel.ods
- (42.43 KiB) 105-mal heruntergeladen
Re: Python Listenfeld
Moin,
ich werde die Frage anders formulieren:
Für ein libreoffice calc basierendes Projekt versuche ich mit Python eine App hinzukriegen. Es wird eine GUI mit zwei Listboxes und drei Buttons geben. Die GUI wird mit tkinter erstellt. In der Gui wird es ein listbox widget zur Auswahl eines Monats geben.
Mit dem Button btnShow wird dann die function _setFilter ausgelöst. Das funktioniert soweit.
ich benötige den Index des ausgewählten Monats. Hier der Code dazu.
Auserhalb dieser Klasse möchte ich die in der Listbox getroffene Auswahl in der folgenden Function weiterverarbeiten:
Meine Frage dazu:
Wie bekomme ich es hin, den in der Listbox lbMonth selectierten Eintrag in der function _setFilter weiterverarbeiten zu können?
Ach ja, main sieht so aus:
es fragt
Gerd
ich werde die Frage anders formulieren:
Für ein libreoffice calc basierendes Projekt versuche ich mit Python eine App hinzukriegen. Es wird eine GUI mit zwei Listboxes und drei Buttons geben. Die GUI wird mit tkinter erstellt. In der Gui wird es ein listbox widget zur Auswahl eines Monats geben.
Mit dem Button btnShow wird dann die function _setFilter ausgelöst. Das funktioniert soweit.
ich benötige den Index des ausgewählten Monats. Hier der Code dazu.
Code: Alles auswählen
class dlgZeitzettel(tk.Tk):
@property # getter _indexMonth
def indexMonth(self):
return self._indexMonth
def __init__(self):
super().__init__()
self.geometry('300x200')
self.grid_columnconfigure(5, weight = 0)
self.grid_rowconfigure(4, weight = 0)
self.resizable(False, False)
self._createWidgets()
self._aMonth = 0 # selected tuple from lbMonth
self._indexMonth = 0 # index +1 of selected tuple in lbMonth
self._strMonth = None # Month as string in selected Tuple in lbMonth
def _createWidgets(self):
# ----------- label for lbMonth
self.lblMonth = tk.Label(self, text= 'Monat : ')
self.lblMonth.grid(row=0, column=3)
# ----------- listbox lbMonth
self.itemsMonth = tk.StringVar(value=_getMonth())
# self.lbMonth.delete(0, tk.END)
self.lbMonth = tk.Listbox(self, activestyle='dotbox',
selectmode=tk.BROWSE,
height=5, width=10,
listvariable=self.itemsMonth)
self.lbMonth.grid(row=1, column=3 )
self.lbMonth.bind('<<ListboxSelect>>', self._onSelectMonth)
# ---------- the show button
self.btnShow= ttk.Button(self, text='Show', command=_setFilter)
self.btnShow.grid(row=3, column=3)
def _onSelectMonth(self, event):
"""
Listener for listbox lbMonth
all messageboxes are only for
debugging reasons!
"""
box = event.widget
self._indexMonth = box.curselection() # index of selected tuple in lbMonth
messagebox.showinfo("Monat Nummer :", f'selected: {self._indexMonth[0]+1}') # show index
self._strMonth = box.get(self._indexMonth) #selected Monatsname
# messagebox only for debugging reasons
messagebox.showinfo("Monat Name :", f'selected: {self._strMonth}') # show name
g_exportedScripts = (main, )
Auserhalb dieser Klasse möchte ich die in der Listbox getroffene Auswahl in der folgenden Function weiterverarbeiten:
Code: Alles auswählen
def _setFilter():
""" set Filter in sheet Daten
all messageboxes are only for debugging reasons
"""
_month = dlgZeitzettel.indexMonth # property (indexMonth) in class dlgZeitzettel
_year = dlgZeitzettel.intYear # property in class dlgZeitzettel
_minYear = int(_getMinYear())
# messagebox only for debugging reasons
messagebox.showinfo(" _setFilter before try : ", f"Monat = {_month} Jahr = {_year} min = {_minYear}")
# here comes a try block, not relevant for my question
Meine Frage dazu:
Wie bekomme ich es hin, den in der Listbox lbMonth selectierten Eintrag in der function _setFilter weiterverarbeiten zu können?
Ach ja, main sieht so aus:
Code: Alles auswählen
def main():
window = dlgZeitzettel()
window.title(_VERSION)
window.mainloop()
if __name__ == '__main__':
main()
Gerd
Re: Python Listenfeld
Hallo,
meine Pythonkenntnisse sind eher rudimentär, aber ich bin dabei zu lernen und dein Beispiel zeigt mir eine ganze Menge.
Nun zu deinem Problem:
Zunächst hatte ich mich gewundert, dass die Auswahl des Monat nicht erhalten bleibt, sobald man das Jahr wählt.
Das lässt sich mit der Option exportselection=False lösen.
Bei der eigentlichen Frage scheitere ich. Für mein Verständnis definierst du eine Klasse dlgZeitzettel und eröffnest dann eine Instanz dieser per
Alles was dann ausgehend von diesem Dialog passiert, passiert ereignisgesteuert, Wenn also in den Listboxen etwas gewählt wird z. B. def _onSelectMonth ausgelöst. Diese ist innerhalb der Klasse definiert. def _setFilter wird durch den Button ausgelöst, ist aber außerhalb der Klasse definiert. Die Klasse definiert eine Eigenschaft indexMonth und auf diese müsste man zugreifen können. Nach meinem Verständnis wäre das aber window.indexMonth. Aber das funktioniert (auch) nicht. Irgendwo habe ich da wohl einen Denkfehler ... 
Ergänzung: wenn ich die def _setFilter in die class hineinnehme geht es
Muss das zwingend so sein?
meine Pythonkenntnisse sind eher rudimentär, aber ich bin dabei zu lernen und dein Beispiel zeigt mir eine ganze Menge.
Nun zu deinem Problem:
Zunächst hatte ich mich gewundert, dass die Auswahl des Monat nicht erhalten bleibt, sobald man das Jahr wählt.
Das lässt sich mit der Option exportselection=False lösen.
Code: Alles auswählen
self.lbMonth = tk.Listbox(self, activestyle='dotbox',
selectmode=tk.BROWSE,
height=5, width=10,
listvariable=self.itemsMonth, exportselection=False)
Code: Alles auswählen
window = dlgZeitzettel()

Ergänzung: wenn ich die def _setFilter in die class hineinnehme geht es

Gruß,
mikele
mikele
Re: Python Listenfeld
Moin mikele,
vielen Dank für Deine Reaktion.
In verschiedenen Programmiersprachen versuche ich immer, Dinge zu kapseln. Python ist da für mich auch insofern Neuland, als das ich zum ersten Mal etwas mit tkinter versuche auf die Beine zu stellen. Mein Verständniss dahingehend ist, das in einer Dialogklasse, wie dlgZeitzettel eine ist, alles hineingehört, was für das Sein oder Nichtsein des Dialoges benötigt wird. Dazu gehört die Funktionalität genauso, wie das Styling.
Alles was nicht direkt dazu gehört, gehört auch nicht in die Klasse. Also gehört _setFilter die Funktion macht ja nix in oder für den Dialog sondern soll Daten, die der Dialog sammelt, weiterverarbeiten, wegen der Übersicht also außerhalb der Dialog Klasse, eventuell sogar in eine andere Klasse.
Irgendwas läuft da jedoch schief.
Vielleicht sollte ich die Frage in einem speziellen Python Forum stellen. Ich war der Annahme, das sich hier einige libreoffice-python wissende aufhalten. Augenscheinlich ist mein Problem auch keines, welches libreoffice direkt betrifft.
Es grüßt
Gerd
vielen Dank für Deine Reaktion.
Das war mir noch gar nicht störend aufgefallen, aber wieder was gelernt.
das ist richtig und hat den folgenden Grund:mikele hat geschrieben: ↑Mo 31. Mär 2025, 20:14Bei der eigentlichen Frage scheitere ich. Für mein Verständnis definierst du eine Klasse dlgZeitzettel und eröffnest dann eine Instanz dieser perCode: Alles auswählen
window = dlgZeitzettel()
In verschiedenen Programmiersprachen versuche ich immer, Dinge zu kapseln. Python ist da für mich auch insofern Neuland, als das ich zum ersten Mal etwas mit tkinter versuche auf die Beine zu stellen. Mein Verständniss dahingehend ist, das in einer Dialogklasse, wie dlgZeitzettel eine ist, alles hineingehört, was für das Sein oder Nichtsein des Dialoges benötigt wird. Dazu gehört die Funktionalität genauso, wie das Styling.
Alles was nicht direkt dazu gehört, gehört auch nicht in die Klasse. Also gehört _setFilter die Funktion macht ja nix in oder für den Dialog sondern soll Daten, die der Dialog sammelt, weiterverarbeiten, wegen der Übersicht also außerhalb der Dialog Klasse, eventuell sogar in eine andere Klasse.
Vielleicht liegt da ja mein Denkfehler. Warum kann ich mir das fedoch nicht vorstellen? Weil in der mir vorliegenden Literatur davon gesprochen wird, das Variablen in einer Klasse funktionen auserhalb derselben durch getter (kenne ich auch aus anderen Sprachen) zur Verfügung gestellt werden. Das geschieht in Python durch den Decorateur @property. Das habe ich gemacht.
Irgendwas läuft da jedoch schief.
Vielleicht sollte ich die Frage in einem speziellen Python Forum stellen. Ich war der Annahme, das sich hier einige libreoffice-python wissende aufhalten. Augenscheinlich ist mein Problem auch keines, welches libreoffice direkt betrifft.
Es grüßt
Gerd
Re: Python Listenfeld
Moin zusammen,
viel Anregungen gab es zu diesem Thema ja nicht. Daher mal gefragt: Sind python Makros / Scripte nicht so der Burner in Libreoffice?
Wie dem auch sei. Ich habe die Lösung, zumindest für mich, gefunden.
Mikele hat mich mit diesem
die getroffene Auswahl nicht in Variablen speichern. Diese Verhalten ist aus einer tkinter Listbox als auch aus einer UNO Listbox gleich. Zumindest auf meinem System, ein Debian bookworm mit Libreoffice 25.2.12 und Python 3.11
Ich habe das Ganze jetzt dahingehend geändert das ich den Button btnShow, der letztlich eine function auserhalb der Dialogklasse aufrufen soll, mittels
ein command mitgegeben.
In _btnShowClicked werden jetzt die selectedItems aus den zwei Listboxen, mit denen jeweils zu bearbeitendes Jahr und Monat ausgewählt wird, in Variablen gespeichert und als Parameter dem Aufruf der auserhalb der Klasse liegenden Function mitgegeben. Funktioniert, wie ich es mir gewünscht habe.
@Mikele Danke für Deinen Denkanstoß
Es grüßt
Gerd
viel Anregungen gab es zu diesem Thema ja nicht. Daher mal gefragt: Sind python Makros / Scripte nicht so der Burner in Libreoffice?
Wie dem auch sei. Ich habe die Lösung, zumindest für mich, gefunden.
Mikele hat mich mit diesem
auf einen Gedanken gebracht, den ich so ohne weiteres nicht verfolgt hätte. Irgendwie lässt sich imCode: Alles auswählen
self.lbMonth = tk.Listbox(self, activestyle='dotbox', selectmode=tk.BROWSE, height=5, width=10, listvariable=self.itemsMonth, exportselection=False)
Code: Alles auswählen
self.lbMonth.bind('<<ListboxSelect>>', self._onSelectMonth)
def _onSelectMonth(self, event):
Ich habe das Ganze jetzt dahingehend geändert das ich den Button btnShow, der letztlich eine function auserhalb der Dialogklasse aufrufen soll, mittels
Code: Alles auswählen
self.btnShow= ttk.Button(self, text='Show', command = self._btnShowClicked)
In _btnShowClicked werden jetzt die selectedItems aus den zwei Listboxen, mit denen jeweils zu bearbeitendes Jahr und Monat ausgewählt wird, in Variablen gespeichert und als Parameter dem Aufruf der auserhalb der Klasse liegenden Function mitgegeben. Funktioniert, wie ich es mir gewünscht habe.
Code: Alles auswählen
_setTest(self._intMonth, self._intYear)
Es grüßt
Gerd
An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:
Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.