Closed LalFX closed 2 years ago
Hello @LalFX, A quick example that comes to mind is the following:
#!/usr/bin/python3
import pathlib
import pygubu
PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = PROJECT_PATH / "centered_demo.ui"
class CenteredDemoApp:
def __init__(self, master=None):
self.builder = builder = pygubu.Builder()
builder.add_resource_path(PROJECT_PATH)
builder.add_from_file(PROJECT_UI)
self.mainwindow = builder.get_object("topmain", master)
builder.connect_callbacks(self)
# center window on screen after creation
self.mainwindow.after(200, self.center_window)
def center_window(self):
"""Center a toplevel on screen."""
toplevel = self.mainwindow
height = toplevel.winfo_height()
width = toplevel.winfo_width()
x_coord = int(toplevel.winfo_screenwidth() / 2 - width / 2)
y_coord = int(toplevel.winfo_screenheight() / 2 - height / 2)
geom = f'{width}x{height}+{x_coord}+{y_coord}'
toplevel.geometry(geom)
def run(self):
self.mainwindow.mainloop()
if __name__ == "__main__":
app = CenteredDemoApp()
app.run()
<?xml version='1.0' encoding='utf-8'?>
<interface version="1.2">
<object class="tk.Toplevel" id="topmain">
<property name="geometry">320x240</property>
<property name="height">200</property>
<property name="width">200</property>
<child>
<object class="ttk.Frame" id="fmain">
<property name="height">200</property>
<property name="width">200</property>
<layout manager="pack">
<property name="expand">true</property>
<property name="side">top</property>
</layout>
<child>
<object class="ttk.Label" id="label1">
<property name="font">{Helvetica} 24 {}</property>
<property name="text" translatable="yes">Center Me</property>
<layout manager="pack">
<property name="side">top</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</interface>
Let me know if this helps. Regards Alejandro A.
That works great! Thanks. However, there seems to be a blip where the window appears on one end of the screen and then realigns itself. Is there anyway to avoid the blip?
I reduced the time limit after the "self.mainwindow.after" to 0, but there is still a blip that happens.
Hello, What OS are you running? What python version?
Another option could be:
#!/usr/bin/python3
import pathlib
import pygubu
PROJECT_PATH = pathlib.Path(__file__).parent
PROJECT_UI = PROJECT_PATH / "centered_demo.ui"
class CenteredDemoApp:
def __init__(self, master=None):
self.builder = builder = pygubu.Builder()
builder.add_resource_path(PROJECT_PATH)
builder.add_from_file(PROJECT_UI)
self.mainwindow = builder.get_object("topmain", master)
builder.connect_callbacks(self)
# center window on screen after creation
self._first_init = True
self.mainwindow.bind('<Map>', self.center_window)
def center_window(self, event):
if self._first_init:
print('centering window...')
toplevel = self.mainwindow
height = toplevel.winfo_height()
width = toplevel.winfo_width()
x_coord = int(toplevel.winfo_screenwidth() / 2 - width / 2)
y_coord = int(toplevel.winfo_screenheight() / 2 - height / 2)
geom = f'{width}x{height}+{x_coord}+{y_coord}'
toplevel.geometry(geom)
self._first_init = False
def run(self):
self.mainwindow.mainloop()
if __name__ == "__main__":
app = CenteredDemoApp()
app.run()
Regards Alejandro A.
Hello, I'm actually working on a new pull request that will add a new option to center the preview window. I will submit it sometime this week. I just need to test it.
Hi alejandroautalan: Thanks for the rapid response. This version on the sample is perfect. However, on my UI (which has more elements - its still blips for a millisecond. I got the same sort of effect when I reduced the "after" time on the earlier code to 0 seconds.
Jrezai: That is brilliant! Looking forward to the revised version. If you can add a Splash image option - that would be the icing on the cake!
My OS is Window 10 (21H1) Python: 3.10.1
@LalFX As I read your question more closely, I realize now you're looking to center the window in your own project. My pull request will be for centering the preview window in Pygubu Designer, not the end-user's final project.
Centering a window can be a little bit complicated depending on which OS you have.
For example, in Linux (which is what I use mostly), if I use: root.winfo_screenwidth()
, it will give me the width of my 2 monitors combined. Each of my monitors has a width of 1920 pixels (wide), so that function will return: 3840 (1920 x 2), which is not what I expect. In Windows, however, it will return 1920. I'm not sure what MacOS will do.
To get around this, I'll be using the screeninfo module which will return the width of each monitor separately. So I'm afraid my pull request won't be exactly 100% what you're looking for, but I hope the info I provided you helped.
Thanks for the info provided I managed to get the main window in the middle of the screen. Is there any way to center the second level windows into the middle of the screen as well?
I managed to create an about window following some of the examples, however, tweaking the earlier code did not get me to position the window in the middle of the screen. This is what I tired and while it opens up the second window, it does not position it anywhere.
def call_about(self):
builder2 = Builder()
builder2.add_from_file(PROJECT_UI)
top2 = Toplevel(self.mainwindow)
frame2 = builder2.get_object('frm_about', top2)
builder2.connect_callbacks(self)
height = frame2.winfo_height()
width = frame2.winfo_width()
x_coord = int(frame2.winfo_screenwidth() / 2 - width / 2)
y_coord = int(frame2.winfo_screenheight() / 2 - height / 2)
geom = f'{width}x{height}+{x_coord}+{y_coord}'
frame2.bind('<Map>', geom)
For anyone who was stuck trying to sort this issue out. The following code seems to work. I made a mistake of trying to tie the frame to the 'geometry' tag. I hard coded the size of the about pop-up as it seemed the most efficient way to do it. Change that based on your requirement.
def call_about(self):
builder2 = Builder()
builder2.add_from_file(PROJECT_UI)
top2 = Toplevel(self.mainwindow)
frame2 = builder2.get_object('frm_about', top2)
builder2.connect_callbacks(self)
height = 220
width = 220
x_coord = int((top2.winfo_screenwidth()/2) - (width/2))
y_coord = int((top2.winfo_screenheight()/2) - (height/2))
geom = f'{width}x{height}+{x_coord}+{y_coord}'
top2.geometry(geom)
Is there any way to center a pygubu window in the middle of the os screen? At the moment it opens up at random locations and I could not find anything in my search to center the ui in the middle of the screen. Any help will be appreciated.