Inherit boot modules and variables in a Python script for another Python script with Gtk3

Asked

Viewed 132 times

0

Good night! I am working with Gtk3 and Python3 and am structuring my project to build an ERP for GNU/LINUX platform. I’m using Glade to build the GUI and using Gtk Builder to manipulate the GUI components. In the example below I intended to exemplify my idea in a very generic way with two acquisitions . py one for each window as I want to structure my design into separate modules where I can call one at a time not to overload the machines where it will run, always taking into account that I need to build a light system for machines that are already outdated :(.

File 1 (Window 1) :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gi
import base64
import zlib
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

ui = Gtk.Builder()
ui.add_from_string(zlib.decompress(base64.b64decode(b'eJyNksFSwjAQhu88xbpXp0D14qGtM86IL6DjsbNNFhpZE0xSkEfyOXwxgxUBYdRbJvn23/33T3H9+iywZB+MsyXmwzECW+W0sbMSH+4n2RVeV4PiLMvgji17iqxhZWILMyHNcDm8uBjmkGUJMjayn5LiagBQeH7pjOcAYpoSZ3F+jrtGqWyMo0/ONU+sIiihEEq8i/NHY7VbIRhd4hNZFspxQyZ24d2CfVyDpWcuUZGtp051AasJSeBitAW++GBmluSL1hyid2uElqwW9iWSqwMZX/dd6hwhrGix4NTYun68JKJaI7o/b0aQZLB1otlvgdEe8YM+MnfTxehsb66J9aG/Ux6FGhaE6MkGoUiNpMs1J8u3IRK8vwFBrwL5T/+n9JYmmKSB1b3vjhb2x5L/W+JZsVlyqDVPqZP4S+VBQkqMmrPeS2hz47rvNZ3KZxNAv+ajOHYPxWjvc34Ayi/vWQ==')).decode("utf-8"))

class Janela1(object):

    def __init__(self, *args, **kwargs):
        super(Handler, self).__init__(*args, **kwargs)
    # --> Inicialização
        self.usuario = "TESTE" # --> Gostaria de herdar a variável de inicialização dessa janela1 para janela2
    
    # -- ao sair da janela1 destroy a aplicação
    def ao_sair_janela_1(self, *args):
        Gtk.main_quit()
    
    # -- Ao clicar no botão da janela1 é impresso na saida padrão a
    # -- mensagem e posteriormente chamo a janela2
    def clicou_janela1(self, *args):
        print("Clicou janela 1")
        
        import janela2 as janela #--> Aqui importo o script da janela2 e apelido de "janela"
        janela.execucao(classe=janela.Janela2) #--> Chamo minha função na janela2 aonde ligo os sinais 
                                               #--> da janela e crio um loop do Gtk para segunda Janela
        
ui.connect_signals(Janela1())
window = ui.get_object("janela1")
window.show_all()

if __name__ == '__main__':
    Gtk.main()

File 2 (Window 2):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gi
import os
import base64
import zlib
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
ui = Gtk.Builder()
# --> (Dúvida: da linha 4 a 10 não queria importar esses módulos novamente,
# --> gostaria de herdar eles da primeira janela)

# --> Arquivo da janela2 
def modulo(string=b'eJyNkk1SAjEQhfecou2tNfy5cTEDVVYJF8BySfUkDQSaBJMMyJE8hxczOFCgQ6G7VPK9/nkv+fB9LbBlH4yzBfbaXQS2ymlj5wW+TEbZIw4Hrfwuy2DMlj1F1rAzcQFzIc3w0O732z3IsgQZG9nPSPGgBZB7fquM5wBiygLncXWP50ZJ1sXON+fKJasISiiEAsdx9WqsdjsEowtckmWhPh7IxG6827CPe7C05gIV2enMqSrgYEQSOO+cgOv82mkSHEx81USDmVuSI6g5RO/2CAuyWtgXSG4ayPjpaSAIO9psOI1oXb1IqqEWRnR9PjSXZMXCiWZ/AjoXxC+6YcNTFaOztQ1lPDbu4UnQ3E6oZEGInmwQilRKutxzMuc5RILPDyCoq0D/9/rX6m1NMKnGdb/+iOO/Es+KzZbDVPOMKok3lD8CUmLUivVFQIcbV93M5xBAbXMjjvND3rn4xl9Nhv2k'):
    return string

# --> Conexão dos sinais e criação do Loop para janela
def execucao(classe=None):
    ui.connect_signals(classe())
    Gtk.main()
    
class Janela2(object):
    def __init__(self, interface=modulo(), *args, **kwargs):
        ui.add_from_string(zlib.decompress(base64.b64decode(interface)).decode("utf-8"))
        super(Janela2, self).__init__(*args, **kwargs)
    # --> Inicialização
        self.janela2 = ui.get_object("janela2")
        self.janela2.show_all()
    
    # -- Fecha a janela2
    def ao_sair_janela2(self, *args):
        Gtk.main_quit()
    
    # -- Exibe a mensagem quando clicado no botão da janela2
    def clicou_janela2(self, *args):
        print("Clicou na janela 2")

My doubt is even how to inherit the modules already imported in window 1 to window 2, as well as the variables of startup of window 1 to window 2

If anyone can give me a hand I’d appreciate it! Thanks!

2 answers

1

Specifically about your doubt:

If your program has several times the same import in different . py files, the Python does not load other copies of the imported module. Only the first import brings the code to memory. Other imports of "zlib" or "Base64", to speak of this example, only create new variables, at the point where the 'import' command is, referencing the same object in memory.

Now, some comments on its architecture:

Having the code for 1 or 20 windows in a single Python application will not "increase the weight" of your system - don’t worry about it: the code used by the OS stack, + graphic ambietne + Python database connectors + Python Runtime must need between 600 and 800MB to work. Each module of your system, even if it is quite complex, will use memory equivalent to what the description of the module in source code uses - that is, even a very complex file will hardly pass the 100KB of extra "weight" .

You can only "spend memory" significantly if you try, for example, to load the box movement of several days of operation into memory, and keep operating with it.

Summary so far: you don’t need to split your application for "performance issue" - you can split the modules to worry about keeping the system organized and maintainable. If it increases complexity, you’re going against the grain.

Now-the way you chose to maintain the Glade-generated interface in your system is also not practical: you have essentially compiled code within your source files - the ideal is to keep the XML files in a folder, close to your files . py same, and load from a file.

The "performance gain" of having the interface description in a string base-64 Inline, zipped, embedded in its source code is negligible - this if there is any gain, and it is very possible that no. On the other hand, you lose a lot, but a lot, in how easy it is to keep your code: any change in the interface you have to use Glade, generate the string with the interface,and "paste" it inside of your app source code. it is much simpler if the files that Glade generates staying in the file system direct -- you change what you need and your file . py keeps working without needing any changes.

If you want to deliver a single file to the end user, then seeing about Packaging, you will see that you can create a ". Egg" or "file. wheel" that contains your code along with the xml and can be used directly - although ideally fly mnta things so that on each machine is executed a "Pip install" of your project - and this already copies all the files necessary for its execution in the Python installation where the command "Pip".

-- Last hint: you are calling "gtk.main()" at more than one point - this is not right - gtk.main should be called only once in the application - you can hide one window and present another, with calls inside gtk.

  • Boa Tarde jsbueno!

  • thank you for answering I believe I am on the right track so I was a little afraid to keep importing modules to each window and cause a problem of excess memory used.

  • Regarding gtk.main() I will restructure the process and any questions I ask again.

  • now regarding boot variables for example when I call a new module I want to pass to it some information, example the user who called this module among other things, when I am working on a project that exists a single file of Glade I use only Gtk calls to windows now when I left for a separate structuring in modules I had this doubt, and ended up assembling this gambiarra to work in part.

  • I don’t know if there is any content that addresses this issue specifically, using Python or C so I can study.

  • you cannot pass variables by "modules' -but since it is defined your window without classes - yes, when you create a class, you can pass parameters, which have seen parameters in Métod 'init" - and these parameters can be gtk controls in the first window, where methods in the second window can read values, for example - do not need to be frozen values.

Show 1 more comment

0


Good night, you guys! I believe I have arrived at a functional model to solve my problem, I only wanted to orientate you if I am on the right track. The modifications I made was that instead of using the Gtk add_from_string.Builder I started using add_from_objects_string because it was better suited to my project structuring model. I also fixed the problem of having to create a new Gtk.main() loop for building the second window, now as friend @jsbueno guided me to make calls only from Gtk, and the properties I need to inherit in the second window have turned class parameters from the same. Below follows the two files that made the modifications:

File 1 (Window 1):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gi
import base64
import zlib
import sqlite3

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

ui = Gtk.Builder()
janela1 = (zlib.decompress(base64.b64decode(b'eJyNksFSwjAQhu88xbpXp0D14qGtM86IL6DjsbNNFhpZE0xSkEfyOXwxgxUBYdRbJvn23/33T3H9+iywZB+MsyXmwzECW+W0sbMSH+4n2RVeV4PiLMvgji17iqxhZWILMyHNcDm8uBjmkGUJMjayn5LiagBQeH7pjOcAYpoSZ3F+jrtGqWyMo0/ONU+sIiihEEq8i/NHY7VbIRhd4hNZFspxQyZ24d2CfVyDpWcuUZGtp051AasJSeBitAW++GBmluSL1hyid2uElqwW9iWSqwMZX/dd6hwhrGix4NTYun68JKJaI7o/b0aQZLB1otlvgdEe8YM+MnfTxehsb66J9aG/Ux6FGhaE6MkGoUiNpMs1J8u3IRK8vwFBrwL5T/+n9JYmmKSB1b3vjhb2x5L/W+JZsVlyqDVPqZP4S+VBQkqMmrPeS2hz47rvNZ3KZxNAv+ajOHYPxWjvc34Ayi/vWQ==')).decode("utf-8"))
ui.add_objects_from_string(janela1, ["janela1"])

class Handler(object):
    def __init__(self, *args, **kwargs):
        super(Handler, self).__init__(*args, **kwargs)
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # --> Inicialização
        self.window = ui.get_object("janela1")
        self.window.show_all()
        
        self.conexao = sqlite3.connect("banco.db")
        self.cursor = self.conexao.cursor()
        
    def ao_sair_janela_1(self, *args):
        Gtk.main_quit()
    
    # -- Sinal conectado a um GtkButton
    def clicou_janela1(self, *args):
        print("Clicou janela 1")
        from janela2 import Janela2
        Janela2(construtor=ui, conexao=self.conexao, cursor=self.cursor)
        
ui.connect_signals(Handler())
if __name__ == '__main__':
    Gtk.main()

File 2 (Window 2):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gi
import base64
import zlib

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

janela2 = (zlib.decompress(base64.b64decode(b'eJyNkk1uAjEMhfecwvW2Gv666WIGpEqFC1B1iTyJgYBJaJKBcqSeoxdr6ICgHUS7i5zvOfZ7yYfva4Et+2CcLbDX7iKwVU4bOy/wZTLKHnE4aOV3WQZjtuwpsoadiQuYC2mGh3a/3+5BliXI2Mh+RooHLYDc81tlPAcQUxY4j6t7PD+UZF3sfHOuXLKKoIRCKHAcV6/GardDMLrAJVkW6uOBTOzGuw37uAdLay5QkZ3OnKoCDkYkgfPOCbjOr50mwcHEV000mLklOYKahSNnvGUbERZktbAvkNw0kPHT01QQdrTZcJrTunqb1EgtjOj6fJhAkh8LJ5r9CehcEL/ohhdPVYzO1l6U8fhwD0+C5opCJQtC9GSDUKRSUnHPyaHnEAk+P4Cg7gL93x5c67c1waQe1037I5P/SjwrNlsOU80zqiTeUP5ISYlRK9YXAR0qrrqZzyGA2uZGHOeLvHPxl78AjX7/XA==')).decode("utf-8"))

class Janela2(object):
    def __init__(self, construtor, usuario=None, conexao=None, cursor=None, *args, **kwargs):
        super(Janela2, self).__init__(*args, **kwargs)
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # --> Inicialização
        self.construtor = construtor
        self.construtor.add_objects_from_string(janela2, ["janela2"])
        self.construtor.connect_signals(self)
        self.conexao = conexao
        self.cursor = cursor
        
        self.cursor.execute(" create table if not exists login("
                            " usuario text not null,"
                            " senha text not null)")
        self.conexao.commit()
        self.window = self.construtor.get_object("janela2")
        self.window.show_all()
    
    
    # -- Sinal conectado a uma GtkWindow
    def ao_sair_janela2(self, *args):
        jn = self.window 
        jn.destroy()
        return True
    
    # -- Sinal conectado a um GtkButton
    def clicou_janela2(self, *args):
        print("Clicou na janela 2")

In the second window I even demonstrated what I needed to inherit actually from the first window, and it’s working, now if it’s right enough to become a model for building multiple modules following the same mold I’m not sure, I needed your help.

Thank you in advance!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.