Если вы столкнулись с этой проблемой при использовании Maven , вы можете скомпилировать свой код с помощью подключаемого модуля Maven Compiler .
org.apache.maven.plugins
maven-compiler-plugin
3.1
1.6
.....
UPDATE: установите source
и target
на 1.8
, если вы используете JDK 8.
Вы можете попробовать использовать методы winfo_screenwidth
и winfo_screenheight
, которые возвращают соответственно ширину и высоту (в пикселях) вашего экземпляра Tk
(окно), а с помощью некоторой базовой математики вы можете центрировать свое окно:
import tkinter as tk
from PyQt4 import QtGui # or PySide
def center(toplevel):
toplevel.update_idletasks()
# Tkinter way to find the screen resolution
# screen_width = toplevel.winfo_screenwidth()
# screen_height = toplevel.winfo_screenheight()
# PyQt way to find the screen resolution
app = QtGui.QApplication([])
screen_width = app.desktop().screenGeometry().width()
screen_height = app.desktop().screenGeometry().height()
size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
x = screen_width/2 - size[0]/2
y = screen_height/2 - size[1]/2
toplevel.geometry("+%d+%d" % (x, y))
toplevel.title("Centered!")
if __name__ == '__main__':
root = tk.Tk()
root.title("Not centered")
win = tk.Toplevel(root)
center(win)
root.mainloop()
Я вызываю метод update_idletasks
, прежде чем извлекать ширину и высоту окна, чтобы гарантировать верность возвращаемых значений.
Tkinter не видит, есть ли два или более монитора расширенного горизонтального или вертикального. Таким образом, вы получите общее разрешение всех экранов вместе, и ваше окно окажется где-то посередине экранов.
PyQt , с другой стороны, также не видит среду с несколькими мониторами, но она получит только разрешение монитора Top-Left (Imagine 4 monitor, 2 up и 2 вниз, делая квадрат). Таким образом, это делает работу, помещая окно в центр этого экрана. Если вы не хотите использовать оба параметра, PyQt и Tkinter , возможно, лучше начать с PyQt с начала.
Я использую функцию frame и expand. Очень просто. Я хочу несколько кнопок в середине экрана. Окно изменения размера и кнопки остаются посередине. Это мое решение.
frame = Frame(parent_window)
Button(frame, text='button1', command=command_1).pack(fill=X)
Button(frame, text='button2', command=command_2).pack(fill=X)
Button(frame, text='button3', command=command_3).pack(fill=X)
frame.pack(anchor=CENTER, expand=1)
Общий подход к центрированию окна заключается в вычислении соответствующих координат экрана для верхнего левого пикселя окна:
x = (screen_width / 2) - (window_width / 2)
y = (screen_height / 2) - (window_height / 2)
Однако это не , достаточное для точно центрирование окна tkinter (по крайней мере, на Windows 7); потому что ширина и высота окна, возвращаемые любым методом , не будут включать самый внешний кадр с кнопками заголовка и min / max / close. Он также не будет включать строку меню (с файлом, редактированием и т. Д.). К счастью, есть способ найти их размеры.
Вот самая основная функция, которая не учитывает вышеупомянутую проблему:
def center(win):
win.update_idletasks()
width = win.winfo_width()
height = win.winfo_height()
x = (win.winfo_screenwidth() // 2) - (width // 2)
y = (win.winfo_screenheight() // 2) - (height // 2)
win.geometry('{}x{}+{}+{}'.format(width, height, x, y))
Альтернативы: winfo_reqwidth()
, winfo_reqheight()
Прежде всего, мы хотим вызвать метод update_idletasks()
в окне окна перед тем, как геометрии, чтобы гарантировать, что возвращаемые значения точны.
Важно понимать строки геометрии , используемые с методом geometry()
. Первая половина - ширина и высота окна, исключая внешний кадр, а вторая половина - верхние левые координаты x и y.
Существует четыре метода, которые позволят нам определить внешний размеры рамки. winfo_rootx()
даст нам координату верхнего левого окна окна, исключая внешний кадр. winfo_x()
даст нам верхнюю левую координату x. Их разница - ширина внешнего кадра.
frm_width = win.winfo_rootx() - win.winfo_x()
win_width = win.winfo_width() + (2*frm_width)
Разница между winfo_rooty()
и winfo_y()
будет нашей высотой заголовка / строки меню.
titlebar_height = win.winfo_rooty() - win.winfo_y()
win_height = win.winfo_height() + (titlebar_height + frm_width)
Вот полная функция в рабочем примере:
import tkinter # Python 3
def center(win):
"""
centers a tkinter window
:param win: the root or Toplevel window to center
"""
win.update_idletasks()
width = win.winfo_width()
frm_width = win.winfo_rootx() - win.winfo_x()
win_width = width + 2 * frm_width
height = win.winfo_height()
titlebar_height = win.winfo_rooty() - win.winfo_y()
win_height = height + titlebar_height + frm_width
x = win.winfo_screenwidth() // 2 - win_width // 2
y = win.winfo_screenheight() // 2 - win_height // 2
win.geometry('{}x{}+{}+{}'.format(width, height, x, y))
win.deiconify()
if __name__ == '__main__':
root = tkinter.Tk()
root.attributes('-alpha', 0.0)
menubar = tkinter.Menu(root)
filemenu = tkinter.Menu(menubar, tearoff=0)
filemenu.add_command(label="Exit", command=root.destroy)
menubar.add_cascade(label="File", menu=filemenu)
root.config(menu=menubar)
frm = tkinter.Frame(root, bd=4, relief='raised')
frm.pack(fill='x')
lab = tkinter.Label(frm, text='Hello World!', bd=4, relief='sunken')
lab.pack(ipadx=4, padx=4, ipady=4, pady=4, fill='both')
center(root)
root.attributes('-alpha', 1.0)
root.mainloop()
Один из способов предотвратить просмотр окна по экрану - использовать .attributes('-alpha', 0.0)
, чтобы сделать окно полностью прозрачный, а затем установите 1.0
после того, как окно будет центрировано. Использование withdraw()
или iconify()
позже, а затем deiconify()
, похоже, не работает, для этой цели, в Windows 7. Обратите внимание, что я использую deiconify()
в качестве трюка для активации окна.
Я нашел решение для того же вопроса на этом сайте
from tkinter import Tk
from tkinter.ttk import Label
root = Tk()
Label(root, text="Hello world").pack()
# Apparently a common hack to get the window size. Temporarily hide the
# window to avoid update_idletasks() drawing the window in the wrong
# position.
root.withdraw()
root.update_idletasks() # Update "requested size" from geometry manager
x = (root.winfo_screenwidth() - root.winfo_reqwidth()) / 2
y = (root.winfo_screenheight() - root.winfo_reqheight()) / 2
root.geometry("+%d+%d" % (x, y))
# This seems to draw the window frame immediately, so only call deiconify()
# after setting correct window position
root.deiconify()
root.mainloop()
Конечно, я изменил его соответственно моим целям, он работает.
Tk предоставляет вспомогательную функцию, которая может сделать это как tk::PlaceWindow
, но я не верю, что она была выставлена как завернутый метод в Tkinter. Вы бы центрировали виджет, используя следующее:
from tkinter import *
app = Tk()
app.eval('tk::PlaceWindow %s center' % app.winfo_pathname(app.winfo_id()))
app.mainloop()
Эта функция также должна иметь дело с несколькими дисплеями. Он также имеет опции для центровки над другим виджетами или относительно указателя (используется для размещения всплывающих меню), чтобы они не падали с экрана.
_tkinter.TclError: window id "2885868" doesn't exist in this application
. Я не думаю, что когда-либо работал над Python 3, но из вашего импорта в нижний регистр, я полагаю, это сработало для вас? Я смог обновить код, используя вместо этого winfo_toplevel: app.eval('tk::PlaceWindow %s center' % app.winfo_toplevel())
– idbrii
17 January 2017 в 20:11
Использование:
import tkinter as tk
if __name__ == '__main__':
root = tk.Tk()
root.title('Centered!')
w = 800
h = 650
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
root.mainloop()
import tkinter as tk
win = tk.Tk() # Creating instance of Tk class
win.title("Centering windows")
win.resizable(False, False) # This code helps to disable windows from resizing
window_height = 500
window_width = 900
screen_width = win.winfo_screenwidth()
screen_height = win.winfo_screenheight()
x_cordinate = int((screen_width/2) - (window_width/2))
y_cordinate = int((screen_height/2) - (window_height/2))
win.geometry("{}x{}+{}+{}".format(window_width, window_height, x_cordinate, y_cordinate))
win.mainloop()