Wie kann ich den GTK Entry Wert auslesen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Benutzeravatar
beli3ver
User
Beiträge: 26
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Samstag 22. Juni 2019, 15:09

Guten Tag,

ich habe eine kleine App die so gestartet wird:

Code: Alles auswählen

class Invoicy(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init__(self)

    def do_activate(self):
        win = MainWindow(self)
        win.show_all()

    def do_startup(self):
        Gtk.Application.do_startup(self)


app = Invoicy()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
Dann in der MainWindow Klasse wird ein Fenster erstellt mit einem Menübutton:

Code: Alles auswählen

class MainWindow(Gtk.ApplicationWindow):

    def __init__(self, app):
        Gtk.Window.__init__(self, title="Invoicy", application=app)
        self.set_border_width = 10
        self.set_default_size(800, 600)

        header_bar = Gtk.HeaderBar()
        header_bar.set_show_close_button(True)
        header_bar.props.title = "Invoicy"
        self.set_titlebar(header_bar)

        menubutton = Gtk.Button()
        image = Gtk.Image.new_from_gicon(Gio.ThemedIcon(name="open-menu"), Gtk.IconSize.LARGE_TOOLBAR)
        menubutton.add(image)
        menubutton.connect("clicked", self.on_menubutton_click)
        header_bar.pack_end(menubutton)
Die Funktion on_menubutton_click erstellt dann ein custom dialog.

Code: Alles auswählen

    def on_menubutton_click(self, widget):
        dialog = Gtk.Dialog()

        dialog.set_default_size(300, 300)
        dialog.set_transient_for(self)
        dialog.set_modal(True)
        grid = Gtk.Grid(column_spacing=10, row_spacing=10)
        grid.props.margin_left = 20
        grid.props.margin_right = 20
        grid.props.margin_top = 20
        grid.props.margin_bottom = 20
        
         companycountry_label = Gtk.Label("Country")
        companycountry_entry = Gtk.Entry()
        
        dialog.add_button(button_text="Save", response_id=Gtk.ResponseType.OK)
        dialog.connect("response", self.set_company_data)

        box = dialog.get_content_area()
        box.add(grid)

        dialog.show_all()
Jetzt würde ich gerne in dieser Funktion, set_company_data den entsprechenden Inhalt von dem Entry abgreifen.
Doch mit diesem Teil bekomme ich diesen Fehler:
AttributeError: 'MainWindow' object has no attribute 'companycountry_entry'

Code: Alles auswählen

    def set_company_data(self,  widget, event):

        print(self.companycountry_entry.get_text())
        widget.destroy()
Wie kann ich jetzt diesen Inhalt abfragen.
Benutzeravatar
__blackjack__
User
Beiträge: 5993
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Samstag 22. Juni 2019, 15:27

@beli3ver: `set_company_data()` müsste das als Argument übergeben bekommen. Schau Dir mal `functools.partial()` an.
long long ago; /* in a galaxy far far away */
Benutzeravatar
beli3ver
User
Beiträge: 26
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Samstag 22. Juni 2019, 15:49

Verstehe ich das richtig, dass 'functools.partial()' nur funktioniert, wenn ich eine Funktion aufrufe:

Code: Alles auswählen


from functools import partial 
  
# A normal function 
def f(a, b, c, x): 
    return 1000*a + 100*b + 10*c + x 
  
# A partial function that calls f with 
# a as 3, b as 1 and c as 4. 
g = partial(f, 3, 1, 4) 
  
# Calling g() 
print(g(5)) 


Sirius3
User
Beiträge: 11979
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 22. Juni 2019, 16:30

@beli3ver: wenn eine überschriebene Methode nichts anderes macht, als ihre Eltern-Methode aufzurufen, dann kann man sie auch ganz weglassen.

Wie kommt `companycountry_entry` eigentlich in den Dialog?
Am einfachsten ist es, eine eigene Dialog-Klasse zu schreiben, die dann companycountry_entry als Attribut haben kann.
Benutzeravatar
beli3ver
User
Beiträge: 26
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Samstag 22. Juni 2019, 17:08

So kommt es da rein:

Code: Alles auswählen

        grid.add(header)
        grid.attach(header_company, 0, 1, 2, 1)
        grid.attach(companycountry_label, 0, 7, 1, 1)
        grid.attach(companycountry_entry, 1, 7, 1, 1)
        box = dialog.get_content_area()
        box.add(grid)
Mit dem ersten Teil deiner Antwort, kann ich leider nichts anfangen.
Danke dir/euch.
Benutzeravatar
__blackjack__
User
Beiträge: 5993
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Samstag 22. Juni 2019, 21:16

@beli3ver: Der erste Teil der Antwort bezog sich auf `Invoicy.__init__()` — da wird nichts sinnvolles gemacht, die kann man komplett weg lassen.
long long ago; /* in a galaxy far far away */
Benutzeravatar
beli3ver
User
Beiträge: 26
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Sonntag 23. Juni 2019, 14:13

Ok danke.
Habe es entsprechend angepasst.
Leider ist mir immer noch nicht ganz bewusst wie ich am besten 'functools.partial()' einsetzen kann:

Code: Alles auswählen

#
# Copyright (c) 2011-2018 Kiefer Networks (https://kiefer-networks.de)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
# Authored by: Malte Kiefer <malte.kiefer@kiefer-networks.de>
#

import gi

gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')

from gi.repository import Gtk, Gio
from Services import dbFiles


class Invoicy(Gtk.Window):

    COMPANY = ""
    CONTACT = ""
    STREET = ""
    ZIP = ""
    PLACE = ""
    COUNTRY = ""
    CURRENCY = ""
    CURRENCYPOSITION = 0

    def __init__(self):
        Gtk.Window.__init__(self, title="Invoicy")
        self.set_border_width = 10
        self.set_default_size(800, 600)

        header_bar = Gtk.HeaderBar()
        header_bar.set_show_close_button(True)
        header_bar.props.title = "Invoicy"
        self.set_titlebar(header_bar)

        newbutton = Gtk.Button()
        image = Gtk.Image.new_from_gicon(Gio.ThemedIcon(name="document-new"), Gtk.IconSize.LARGE_TOOLBAR)
        newbutton.add(image)
        header_bar.pack_start(newbutton)

        menubutton = Gtk.Button()
        image = Gtk.Image.new_from_gicon(Gio.ThemedIcon(name="open-menu"), Gtk.IconSize.LARGE_TOOLBAR)
        menubutton.add(image)
        menubutton.connect("clicked", self.on_menubutton_click)
        header_bar.pack_end(menubutton)

        treestore = Gtk.TreeStore(str, str)

        a = dbFiles.dbFiles()
        invoices = a.read_all_invoices()

        for invoice in invoices:
            treestore.append(None, [invoice['InvoiceNumber'], invoice['Date']])

        treeview = Gtk.TreeView(treestore)
        renderer_number = Gtk.CellRendererText()
        renderer_date = Gtk.CellRendererText()

        col_number = Gtk.TreeViewColumn('Number', renderer_number, text=0)
        col_date = Gtk.TreeViewColumn('Date', renderer_date, text=0)

        treeview.append_column(col_number)
        treeview.append_column(col_date)

        self.add(treeview)

    def on_menubutton_click(self, widget):
        dialog = self.settingsdialog()
        #response = dialog.run()

        #if response == Gtk.ResponseType.OK:
        #    print("The OK button was clicked")
        #elif response == Gtk.ResponseType.CANCEL:
        #    print("The Cancel button was clicked")

        dialog.destroy()

    def settingsdialog (self):
        dialog = Gtk.Dialog()

        dialog.set_default_size(300, 300)
        dialog.set_transient_for(self)
        dialog.set_modal(True)
        dialog.add_button(button_text="Save", response_id=Gtk.ResponseType.OK)
        dialog.connect("response", self.set_company_data)

        grid = Gtk.Grid(column_spacing=10, row_spacing=10)
        grid.props.margin_left = 20
        grid.props.margin_right = 20
        grid.props.margin_top = 20
        grid.props.margin_bottom = 20

        self.get_company_data(self)

        header = Gtk.Label()
        header.set_markup("<big><b>Settings</b></big>")
        header_company = Gtk.Label()
        header_company.set_markup("<b>Company</b>")
        finance_company = Gtk.Label()
        finance_company.set_markup("<b>Finance</b>")

        companyname_label = Gtk.Label("Company")
        companyname_entry = Gtk.Entry()
        companyname_entry.set_text(Invoicy.COMPANY)

        companycontact_label = Gtk.Label("Name")
        companycontact_entry = Gtk.Entry()
        companycontact_entry.set_text(Invoicy.CONTACT)

        companystreet_label = Gtk.Label("Street")
        companystreet_entry = Gtk.Entry()
        companystreet_entry.set_text(Invoicy.STREET)

        companyzip_label = Gtk.Label("ZIP")
        companyzip_entry = Gtk.Entry()
        companyzip_entry.set_text(Invoicy.ZIP)

        companyplace_label = Gtk.Label("Place")
        companyplace_entry = Gtk.Entry()
        companyplace_entry.set_text(Invoicy.PLACE)

        companycountry_label = Gtk.Label("Country")
        companycountry_entry = Gtk.Entry()
        companycountry_entry.set_text(Invoicy.COUNTRY)

        financecurrency_label = Gtk.Label("Currency Symbole")
        financecurrency_entry = Gtk.Entry()
        financecurrency_entry.set_text(Invoicy.CURRENCY)

        financecurrencyposition_label = Gtk.Label("Position Currency Symbole")
        financecurrencyposition_combo = Gtk.ComboBoxText()
        financecurrencyposition_combo.insert(0, "0", "Before")
        financecurrencyposition_combo.insert(1, "1", "After")
        financecurrencyposition_combo.set_active(Invoicy.CURRENCYPOSITION)

        grid.add(header)
        grid.attach(header_company, 0, 1, 2, 1)

        grid.attach(companyname_label, 0, 2, 1, 1)
        grid.attach(companyname_entry, 1, 2, 1, 1)
        grid.attach(companycontact_label, 0, 3, 1, 1)
        grid.attach(companycontact_entry, 1, 3, 1, 1)
        grid.attach(companystreet_label, 0, 4, 1, 1)
        grid.attach(companystreet_entry, 1, 4, 1, 1)
        grid.attach(companyzip_label, 0, 5, 1, 1)
        grid.attach(companyzip_entry, 1, 5, 1, 1)
        grid.attach(companyplace_label, 0, 6, 1, 1)
        grid.attach(companyplace_entry, 1, 6, 1, 1)
        grid.attach(companycountry_label, 0, 7, 1, 1)
        grid.attach(companycountry_entry, 1, 7, 1, 1)

        grid.attach(finance_company, 0, 8, 2, 1)
        grid.attach(financecurrency_label, 0, 9, 1, 1)
        grid.attach(financecurrency_entry, 1, 9, 1, 1)
        grid.attach(financecurrencyposition_label, 0, 10, 1, 1)
        grid.attach(financecurrencyposition_combo, 1, 10, 1, 1)

        box = dialog.get_content_area()
        box.add(grid)

        dialog.show_all()


    @staticmethod
    def get_company_data(self):
        company = dbFiles.dbFiles()
        company_data = company.read_company()

        for data in company_data:
            if 'Name' in data:
                Invoicy.COMPANY = data["Name"]
            if 'Contact' in data:
                Invoicy.CONTACT = data["Contact"]
            if 'Street' in data:
                Invoicy.STREET = data["Street"]
            if 'ZIP' in data:
                Invoicy.ZIP = data["ZIP"]
            if 'Place' in data:
                Invoicy.PLACE = data["Place"]
            if 'Country' in data:
                Invoicy.COUNTRY = data["Country"]
            if 'Currency' in data:
                Invoicy.CURRENCY = data["Currency"]
            if 'CurrencyPositon' in data:
                Invoicy.CURRENCYPOSITION = data["CurrencyPositon"]

    def set_company_data(self,  widget, event):

        print(self.companycountry_entry.get_text())
        widget.destroy()

win = Invoicy()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

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

Sonntag 23. Juni 2019, 14:49

@beli3ver: Also erst einmal sind die Klassenattribute falsch. Richtig ist, das die entsprechend den Konventionen von Konstanten benannt sind (KOMPLETT_GROSS), falsch ist, dass das im Programm aber Variablen sind, die auf Klassenebene nichts zu suchen haben.

`functools.partial()` würde ich hier gar nicht verwenden, denn das unterscheidet sich ja nun doch deutlich von der Eingangsfrage wo es um *ein einziges* Eingabefeld ging. Bei acht Eingabefeldern ist das wie Sirius3 schon vorgeschlagen hat, ein Fall für eine eigene Klasse.

Eventuell lohnt sich auch mal ein Blick auf Glade, damit man die GUI nicht als Code schreiben muss, sondern sich den grafischen Teil zusammenklicken kann.
long long ago; /* in a galaxy far far away */
Benutzeravatar
beli3ver
User
Beiträge: 26
Registriert: Mittwoch 2. März 2016, 05:33
Kontaktdaten:

Sonntag 23. Juni 2019, 17:47

Ok.
Dann schreibe ich die Funktion um, dass Sie die entsprechenden Variablen wieder als return zurückliefert.
Ok.
Dann schaue ich mal, wie ich das am besten mit einer eignen Klasse bewerkstellige.
Gebe ich die entrys dann auch als return Werte zurück?
Antworten