Использование расширений TCL для установки собственного стиля окна в Tkinter

pythonware.com/library/tkinter/introduction/… документирует метод overrideredirect, который удалит заголовок и границы, если этого недостаточно, вы должны установить собственный стиль окна, я не уверен, что Tkinter дает вам такой низкоуровневый доступ, если нет, попробуйте что-то вроде расширения TCL twapi.magicsplat.com/ui.html#set_window_style

В более раннем посте я получил это как ответ о том, как получить границу в Tkinter, подобную той, что изображена ниже. Я не знаком с Tcl и его расширениями. Так как же это сделать? Конечная цель в основном состоит в том, чтобы получить границу внизу окна Tkinter.

альтернативный текст

Изменить :

Я использовал следующее в Windows 7, и, похоже, стиль не изменился. Наверное, чего-то не хватает. Любая помощь будет оценена по достоинству, это может быть действительно здорово!

import string, win32ui, win32con
import Tkinter as tk

root = tk.Tk()

frame = win32ui.CreateWindowFromHandle(string.atoi(root.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)

root.mainloop()

person rectangletangle    schedule 22.07.2010    source источник


Ответы (2)


Вы можете сделать это, используя комбинацию пакетов Python win32 API и Tkinter. Что вам нужно знать, так это то, что окно Tk является клиентской частью окна Win32. Взаимодействия оконного менеджера обрабатываются с помощью оболочки, которая является родительской для самого окна Tk. Если у вас есть окно Tkinter 'w', вы можете создать окно PyWin32 для фрейма или просто манипулировать им напрямую. Вы можете получить кадр hwnd, используя w.wm_frame() и анализируя возвращенную шестнадцатеричную строку, или используя GetParent для значения winfo_id из окна Tk (хотя wm_frame, вероятно, будет более надежным).

import string, win32ui, win32con
from Tkinter import *
w = Tk()
frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)

Это удаляет стиль WS_CAPTION и уведомляет окно о том, что его фрейм изменен, что приводит к пересчету геометрии, так что изменение распространяется на дочернее окно Tk.

РЕДАКТИРОВАТЬ --- Следующее гарантирует, что мы изменим стиль окна после того, как окно будет полностью создано и отображено на дисплее.

import string, win32ui, win32con
from Tkinter import *

def decaption(event):
    w = event.widget
    frame = win32ui.CreateWindowFromHandle(string.atoi(w.wm_frame(), 0))
    frame.ModifyStyle(win32con.WS_CAPTION, 0, win32con.SWP_FRAMECHANGED)
    w.bind("<Map>", None)

root = Tk()
root.bind("<Map>", decaption)
root.mainloop()
person patthoyts    schedule 16.08.2011
comment
Возможно, вам просто нужно пересчитать геометрию — вы пытались изменить размер окна и посмотреть, не исчезнет ли заголовок при перерисовке? Если это так, добавления «w.geometry(w.geometry())» достаточно, чтобы повторно подтвердить размер и положение Tk и заставить его пересчитать все. - person patthoyts; 19.08.2011
comment
Да, я попытался добавить (в приведенный выше код) root.geometry(root.geometry()), root.update_idletasks() и root.configure( ширина=225, высота=124). А также изменение геометрии окон вручную (захватив угол и перемещая его). Ни один из них, похоже, не удалил подпись. Можно ли заставить окно перерисовываться на стороне win32api? Проблемы также могут быть вызваны тем, что я вызываю метод root.mainloop(), чтобы запустить цикл обработки событий GUI. - person rectangletangle; 19.08.2011
comment
ОК - происходит то, что вы изменяете стиль до того, как окно отображается, и, вероятно, оно снова изменяется, поскольку оно впервые отображается Tk. Вы можете видеть, что вы переупорядочиваете вещи, чтобы расшифровать окно с помощью функции кнопки. Нажмите кнопку, и надпись исчезнет. В Tk вы можете перехватить событие «Map» для запуска кода после того, как окно будет полностью создано и сопоставлено с дисплеем. Это событие срабатывает всякий раз, когда окна сопоставлены, поэтому после первого раза мы удаляем обратный вызов. См. редактирование для образца. - person patthoyts; 19.08.2011
comment
Да, это сделало это! Благодаря тонну. Я пытался сделать это в течение некоторого времени. Я полагаю, что также смогу использовать это, чтобы запустить некоторые другие собственные стили Windows. - person rectangletangle; 19.08.2011

Одно из решений — нарисовать собственную границу. Используйте overrideredirect, чтобы удалить все украшения, создать сетку/упаковать/поместить холст, который заполняет окно, затем нарисуйте или используйте растровые изображения, чтобы получить желаемый визуальный эффект. Вам придется добавить свои собственные привязки для перемещения и изменения размера окна, но это не так уж сложно.

person Bryan Oakley    schedule 16.08.2011