alejandroautalan / pygubu-designer

A simple GUI designer for the python tkinter module
GNU General Public License v3.0
800 stars 98 forks source link

Allow to use a normal python module for ttk style definitions #211

Closed alejandroautalan closed 7 months ago

alejandroautalan commented 1 year ago

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like

Hello Mark,

Wondering if there is a better way of using the style definitions file. My application is made of up of perhaps a dozen high level widgets generated by pygubu designer. And I use styles everywhere This means that the style code gets generated and included in each widget. This opens the door for these copies to get out of synch where I add/change styles for one widget and forget to regenerate all the other widgets with the changed style file.

I see your problem here. I think that the best solution will be to allow pygubu designer to fully import the styles file as module, and not to execute its content as it is doing now.

Any suggestions here?

I think in some modifications to the designer.

One restriction is that the styles should be created after the root window is instantiated and before any child widget is created. (alejandroautalan/pygubu#282)

Continuing with this idea, the module will need to define the styles inside a method and not at module level. For example, a method named "setup_ttk_styles".

Remove definition file from global configuration and move them to project level properties:

The following example shows how it would look in the future.

Definition file example custom_styles_module.py:

import tkinter as tk
import tkinter.ttk as ttk

def setup_ttk_styles(master=None):

    style = ttk.Style()

    style.configure("MySpecialButton.TButton",
                    font=("helvetica", 12, "bold"),
                    background="green", foreground="white")

Code generated in Application Mode:

#!/usr/bin/python3
import pathlib
import tkinter.ttk as ttk
import pygubu

import custom_styles_module

PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = PROJECT_PATH / "helloapp.ui"

class HelloappApp:
    def __init__(self, master=None):

        self.builder = builder = pygubu.Builder(
            on_first_object=custom_styles_module.setup_ttk_styles)

        builder.add_resource_path(PROJECT_PATH)
        builder.add_from_file(PROJECT_UI)
        # Main widget
        self.mainwindow = builder.get_object("toplevel1", master)
        builder.connect_callbacks(self)

    def run(self):
        self.mainwindow.mainloop()

if __name__ == "__main__":
    app = HelloappApp()
    app.run()

Code generated in Script Mode:

#!/usr/bin/python3
import tkinter as tk
import tkinter.ttk as ttk

import custom_styles_module

class HelloappApp:
    def __init__(self, master=None):
        # build ui
        toplevel1 = tk.Tk() if master is None else tk.Toplevel(master)
        toplevel1.configure(height=200, width=200)
        toplevel1.geometry("320x100")

        # First object created
        custom_styles_module.setup_ttk_styles(toplevel1)

        frame1 = ttk.Frame(toplevel1)
        frame1.configure(height=200, padding=5, width=200)
        frame2 = ttk.Frame(frame1)
        frame2.configure(height=200, width=200)
        label1 = ttk.Label(frame2)
        label1.configure(text='Hello world!')
        label1.pack(side="top")
        frame2.pack(expand="true", side="top")
        button1 = ttk.Button(frame1)
        button1.configure(text='quit')
        button1.pack(anchor="e", side="top")
        frame1.pack(expand="true", fill="both", side="top")

        # Main widget
        self.mainwindow = toplevel1

    def run(self):
        self.mainwindow.mainloop()

if __name__ == "__main__":
    app = HelloappApp()
    app.run()

Let me know what do you think of this approach.

Regards Alejandro A.

Originally posted by @alejandroautalan in https://github.com/alejandroautalan/pygubu-designer/discussions/204#discussioncomment-5901208

alejandroautalan commented 7 months ago

Fixed in pygubu-designer v0.37