alejandroautalan / pygubu

A simple GUI builder for the python tkinter module
MIT License
2.01k stars 213 forks source link

connect_callbacks objects empty #295

Closed wiryonolau closed 1 month ago

wiryonolau commented 1 month ago

Describe the bug connect_callbacks doing nothing, self.objects.items() always empty window and widget is displayed with no error

To Reproduce

<?xml version='1.0' encoding='utf-8'?>
<interface version="1.4" author="PygubuDesigner 0.39.3">
  <project>
    <settings />
    <customwidgets />
  </project>
  <object class="tk.Toplevel" id="mainwindow" named="True">
    <property name="height">480</property>
    <property name="minsize">640|480</property>
    <property name="width">640</property>
    <child>
      <object class="ttk.Button" id="button4">
        <property name="command" type="command" cbtype="simple">on_button_clicked</property>
        <property name="text" translatable="yes">button4</property>
        <layout manager="pack">
          <property name="anchor">center</property>
          <property name="expand">true</property>
          <property name="side">top</property>
        </layout>
      </object>
    </child>
  </object>
</interface>
import os
from pygubu import Builder

class MainWindow:
    def __init__(self, master = None):
        ui_file = os.path.abspath("./test.ui")
        self._builder = Builder()
        self._builder.add_from_file(ui_file)
        self._setup_handlers()

        self._mainwindow = self._builder.get_object("mainwindow", master=master)

    def _setup_handlers(self):  
        self._builder.connect_callbacks(self)

    def on_button_clicked(self):
        print("working")

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

if __name__ == "__main__":
   main = MainWindow()
   main.run()

Expected behavior when button in click , it print output

Screenshots None

Your Environment (please complete the following information):

Additional context Button do nothing, when check on the connect_callbacks function, self.objects always empty

print(self.objects.items(), callbacks_bag)
dict_items([]) <MainWindow object at 0x7fea25d3e450>
alejandroautalan commented 1 month ago

Hello @wiryonolau, thanks for trying pygubu.

You need to call _connectcallbacks after the main widget is created.

import os
from pygubu import Builder

class MainWindow:
    def __init__(self, master = None):
        ui_file = os.path.abspath("./issue295.ui")
        self._builder = Builder()
        self._builder.add_from_file(ui_file)

        self._mainwindow = self._builder.get_object("mainwindow", master=master)

        #
        # Call setup handlers after main window is created.
        #
        self._setup_handlers()

    def _setup_handlers(self):  
        self._builder.connect_callbacks(self)

    def on_button_clicked(self):
        print("working")

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

if __name__ == "__main__":
   main = MainWindow()
   main.run()

Let me know if you have more questions. Regards

Alejandro A.

wiryonolau commented 1 month ago

Hello @wiryonolau, thanks for trying pygubu.

You need to call _connectcallbacks after the main widget is created.

import os
from pygubu import Builder

class MainWindow:
    def __init__(self, master = None):
        ui_file = os.path.abspath("./issue295.ui")
        self._builder = Builder()
        self._builder.add_from_file(ui_file)

        self._mainwindow = self._builder.get_object("mainwindow", master=master)

        #
        # Call setup handlers after main window is created.
        #
        self._setup_handlers()

    def _setup_handlers(self):  
        self._builder.connect_callbacks(self)

    def on_button_clicked(self):
        print("working")

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

if __name__ == "__main__":
   main = MainWindow()
   main.run()

Let me know if you have more questions. Regards

Alejandro A.

Thanks I just found out too. It just for mainwindow or other get_object also required to be called before connect_callbacks ?

alejandroautalan commented 1 month ago

The call to connect_callbacks searches among the created widgets and connects the callbacks.

Example, if you have one toplevel widget:

mainwindow
    > button 1
    > button 2
    > frame a
        > checkbutton 
        > button 5

Just get the main window and then connect the commmands.

    ...
    self.builder.get_object("mainwindow", master=master)
    ...
    self.builder.connect_commands(self)
    ...

Another example, a main window with a large menu definition (defined outside the mainwindow tree in the same ui file) .

mainwindow: Toplevel
    > button 1
    > button 2
mainmenu: Menu
    > File
        > More menu options with commands
        > Quit
    > Other submenu
    ...

Create the main window, the menu, an then connect commands.

    ...
    mainwindow =  self.builder.get_object("mainwindow", master=master)
    menu = self.builder.get_object("mainmenu", mainwindow)
    mainwindow.configure(menu=menu)

    ...
    self.builder.connect_commands(self)
    ...

Regards Alejandro A.

wiryonolau commented 1 month ago

ok thanks.