Reputation: 2401
I am making a program with several screens and each one has its own size, so each time I change of screen I must re-size the App.
The problem is that, when I change the size of the window, Kivy only increase or reduce the lenght of the right and the bottom sides, not the four sides, so the screen always get "uncentered" after change the size.
I'll try to make an example with lines:
-------------------------------- --------------------------------
| Monitor | | |
| -------- | | -------------- |
| | My | | | | | |
| | App | | > | | | |
| -------- | | | | |
| | | |______________| |
-------------------------------- --------------------------------
Like you can see the program only change the lengh of the right and bottom sides.
How can I center again the screen or better change the size of the four sides and not only two?
This is an example of my code but I don't have any idea of what to do:
.py
example:from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
class Screen_Manager(ScreenManager):
pass
class Main(Screen):
def __init__(self, **kwargs):
super(Main, self).__init__(**kwargs)
def on_pre_enter(self):
Window.size = (900, 500)
class Login(Screen):
def __init__(self, **kwargs):
super(Login, self).__init__(**kwargs)
def on_pre_enter(self):
Window.size = (400, 300)
class MyApp(App):
def build(self):
return Screen_Manager()
MyApp().run()
my.kv
example (my
in order to work with MyApp
):<Screen_Manager>:
id: screen_manager
Main:
Login:
<Login>:
name: 'login'
Button:
text: 'Go to Main'
on_press: root.manager.current = 'main'
<Main>:
name: 'main'
Button:
text: 'Go to Login'
on_press: root.manager.current = 'login'
I have found a way but I don't like it much:
def on_pre_enter(self):
# New size
size = (NEW_X, NEW_Y)
# Get the actual pos and knowing the old size calculate the new one
top = Window.top * Window.size[1] / size[1]
left = Window.left * Window.size[0] / size[0]
# Change the size
Window.size = size
# Fixing pos
Window.top = top
Window.left = left
Upvotes: 1
Views: 2300
Reputation: 11
How I currently use is:
pip install pyautogui
# we use pyautogui module to get Windows screen size*
import pyautogui
Window.top = int( (pyautogui.size().height - Window.height) ) / 2)
Window.left = int( (pyautogui.size().width - Window.width) ) / 2)
Upvotes: 0
Reputation: 36
The way I'm doing this is saving the initial Window.center
value and after a resize event I subtract the variation to the Window.left
and Window.top
values. I.e.:
initial_center = None
def build(self):
self.initial_center = Window.center
on window change event:
variation_x = Window.center[0] - self.initial_center[0]
variation_y = Window.center[1] - self.initial_center[1]
Window.left -= variation_x
Window.top -= variation_y
I'm no Python/Kivy expert so there might be some minor improvements to be done here, but I think this solves your problem.
Upvotes: 1
Reputation: 4127
I couldn't find any hint that kivy was able to supply the screen size of the host device, so I hope if there is one, someone will tell us. In the meantime, I borrowed some setup code from another forum. I've only tested it on my macbook, and it seems to work, getting the screen size. I don't know what will happen on windows, or linux, or multiple monitors. But here's the new code:
import sys
"""
returns Monitor size x and y in pixels for desktop platforms, or None for
mobile platforms
Found at:
https://groups.google.com/forum/#!topic/kivy-users/uZYrghb87g0
"""
if sys.platform == 'linux2':
import subprocess
output = subprocess.Popen(
'xrandr | grep "\*" | cut -d" " -f4',
shell=True,
stdout=subprocess.PIPE).communicate()[0]
screenx = int(output.replace('\n', '').split('x')[0])
screeny = int(output.replace('\n', '').split('x')[1])
elif sys.platform == 'win32':
from win32api import GetSystemMetrics
screenx = GetSystemMetrics(0)
screeny = GetSystemMetrics(1)
elif sys.platform == 'darwin':
from AppKit import NSScreen
frame_size = NSScreen.mainScreen().frame().size
screenx = frame_size.width
screeny = frame_size.height
else:
# For mobile devices, use full screen
screenx,screeny = 800,600 # return something
#print "screenx,screeny = ",repr((screenx,screeny))
from kivy.config import Config # config should appear before any other kivy stuff
Config.set('graphics','position','custom')
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
class Screen_Manager(ScreenManager):
pass
def center_window(sizex,sizey):
Window.size = (sizex, sizey)
Window.left = (screenx - sizex)/2
Window.top = (screeny - sizey)/2
class Main(Screen):
def __init__(self, **kwargs):
super(Main, self).__init__(**kwargs)
def on_pre_enter(self):
center_window(900,500)
class Login(Screen):
def __init__(self, **kwargs):
super(Login, self).__init__(**kwargs)
def on_pre_enter(self):
center_window(400, 300)
class MultiScreenApp(App):
def build(self):
return Screen_Manager()
MultiScreenApp().run()
Upvotes: 4