Хобрук: Ваш путь к мастерству в программировании

Воссоздание виджетов Tkinter с новым шрифтом и размером

Я пытаюсь создать программу, которая позволяет пользователю изменять шрифт меток в окне. Мне трудно понять, как именно воссоздать все метки с новыми шрифтами. Вот что у меня есть до сих пор:

import tkinter as tk
from tkinter import messagebox, colorchooser, simpledialog, filedialog, font

root = tk.Tk()
root.withdraw()

screenHieght = root.winfo_screenheight()  # height of the screen
screenWidth = root.winfo_screenwidth()  # width of the screen

windowHieght = screenHieght / 2  # Turtle window is half of screen size
windowWidth = screenWidth / 2

x = (screenWidth / 2) - (windowWidth / 2)
y = (screenHieght / 2) - (windowHieght / 2)

root.geometry('%dx%d+%d+%d' % (windowWidth, windowHieght, x, y))  # Some assistance from Google on centering the window
root.columnconfigure(3, weight=2)
root.columnconfigure(1, weight=1)
root.columnconfigure(5, weight=1)
root.rowconfigure(1, weight=2)
root.rowconfigure(3, weight=1)
root.rowconfigure(4, weight=1)
root.rowconfigure(5, weight=1)
root.configure(background="#a1dbcd")

def changeFont(selection):
    global selectedfont
    global setfontstyle
    print(selection)
    selectedfont = selection
    print(setfontstyle)

def changeSize(val):
    print(val)
    global setfontstyle
    global fontsize
    fontsize = val
    print(setfontstyle)

def newfontstyle():
    global setfontstyle
    global selectedfont
    global fontsize
    setfontstyle = font.Font(family = selectedfont, size = fontsize)


fontsize = tk.IntVar(root)
selectedfont = tk.StringVar(root)
setfontstyle = font.Font(family=selectedfont, size=12, weight='normal')

def atributes():
    while True:
        global setfontstyle
        global selectedfont
        global fontsize
        fontchoose = ["Arial", "Courier New", "Comic Sans MS", "Fixedsys", "MS Sans Serif", "MS Serif", "Symbol",
                      "System",
                      "Times New Roman", "Verdana"]

        selectedfont.set("Arial")
        # Variables and stuff

        label1 = tk.Label(root, text="Select your options", font=setfontstyle).grid(row=1, column=3, pady=10,
                                                                                    sticky=tk.E + tk.W + tk.N + tk.S)
        label2 = tk.Label(root, text="Font Style", font=setfontstyle).grid(row=3, column=5, pady=10,
                                                                           sticky=tk.E + tk.W + tk.N + tk.S)
        fontdropdown = tk.OptionMenu(root, selectedfont, *fontchoose, command=changeFont).grid(row=4, column=5, pady=10,
                                                                                               sticky=tk.E + tk.W + tk.N + tk.S)
        label3 = tk.Label(root, text="Font Size", font=setfontstyle).grid(row=3, column=1, pady=10,
                                                                          sticky=tk.E + tk.W + tk.N + tk.S)
        fontsize = tk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL, command=changeSize).grid(row=4, column=1,
                                                                                                  pady=10,
                                                                                                  sticky=tk.E + tk.W + tk.N + tk.S)
        redoall = tk.Button(root, text="Recreate", font=setfontstyle, command=newfontstyle).grid(
            row=5, column=3, pady=10, sticky=tk.E + tk.W + tk.N + tk.S)

        # print(fontdropdown)
        root.deiconify()
        # root.wait_variable(selectedfont or fontsize)
        root.mainloop()

Спасибо вам за помощь. Я пытался найти ответ в течение нескольких дней.


  • Вам не нужно заново создавать этикетки. Вы можете изменить шрифт существующих меток. См. stackoverflow.com/a/4073037/7432. 02.05.2018
  • Но как мне получить все ярлыки сразу. Есть ли способ использовать цикл for или что-то в этом роде? 02.05.2018
  • Если вы прочитали ссылку, которую я разместил, вам вообще ничего не нужно делать с этикетками. Дайте им всем один и тот же объект шрифта, и тогда вам нужно будет изменить только один объект шрифта. 02.05.2018
  • Извините, я немного запутался. Я почти уверен, что использую setfontstyle в качестве объекта шрифта. Однако, когда я его изменяю, ничего не меняется 02.05.2018
  • Независимо от вопроса, почему вы вызываете mainloop в цикле или это просто ошибка в том, как вы разместили код? Кроме того, пожалуйста, опубликуйте код, который действительно работает. Когда я запускаю ваш код, он ничего не делает (возможно, потому, что ничто не вызывает atributes. 02.05.2018
  • Гм, я не уверен, должен ли я вместо этого изменить его на update? 02.05.2018
  • Ваш root.mainloop() должен находиться в глобальном пространстве имен с root=Tk(). В этом случае я бы поставил root.mainloop() в самый низ вашего скрипта. 02.05.2018
  • Нет. Вам не нужен update и вам не нужно вызывать mainloop в цикле. Вам вообще не нужен этот цикл while True. Это бесполезно. 02.05.2018

Ответы:


1

Вам не нужно ничего воссоздавать. Поскольку вы используете объект шрифта, все, что вам нужно сделать, это изменить этот объект шрифта, и любой шрифт, использующий этот объект, немедленно отобразит новый шрифт.

def changeFont(selection):
    setfontstyle.configure(family=selection)

def changeSize(val):
    setfontstyle.configure(size=val)

В вашем коде есть и другие ошибки, но это отвечает на ваш конкретный вопрос.

Вот краткий пример программы, которая показывает, как виджеты меняются сразу же при изменении атрибута шрифта:

import tkinter as tk
import tkinter.font

font_families = [
    "Arial", "Courier New", "Comic Sans MS", "Fixedsys",
    "MS Sans Serif", "MS Serif", "Symbol",
    "System", "Times New Roman", "Verdana"
]

def changeSize(val):
    appFont.configure(size=val)

def changeFont(family):
    appFont.configure(family=family)


root = tk.Tk()
root.geometry("400x200")

fontFamily = tk.StringVar(value="Arial")
fontSize = tk.IntVar(value=12)

appFont = tk.font.Font(family=fontFamily.get(), size=fontSize.get(), weight='normal')

size_widget = tk.Scale(root, from_=0, to=100, orient=tk.HORIZONTAL,
                       command=changeSize, variable=fontSize)
family_widget = tk.OptionMenu(root, fontFamily, *font_families, command=changeFont)
label = tk.Label(root, text="Hello, world", font=appFont)

label.pack(side="top", fill="both", expand=True)
size_widget.pack(side="bottom", fill="x", expand=False)
family_widget.pack(side="bottom", fill="x", expand=False)

root.mainloop()
02.05.2018
Новые материалы

Шлюз с лицензией OSS, совместимый с Apollo Federation v2, появится в WunderGraph
Сегодня мы рады сообщить, что мы сотрудничаем с поддерживаемой YC Tailor Technologies, Inc. для внедрения Apollo Federation v2. Реализация будет лицензирована MIT (Engine) и Apache 2.0..

Это оно
Ну, я официально уволился с работы! На этой неделе я буду лихорадочно выполнять последние требования Думающего , чтобы я мог сосредоточиться на поиске работы. Что именно это значит?..

7 полезных библиотек JavaScript, которые вы должны использовать в своем следующем проекте
Усильте свою разработку JavaScript Есть поговорка «Не нужно изобретать велосипед». Библиотеки — лучший тому пример. Это поможет вам написать сложные и трудоемкие функции простым способом...

Базовое руководство по переносу концепций обучения в глубокое обучение
Обзор По мере того, как машинное обучение становится все более мощным и продвинутым, модели, обеспечивающие эту расширенную возможность, становятся все больше и начинают требовать огромного..

C в C.R.U.D с использованием React-Redux
Если вы использовали React, возможно, вы знакомы с головной болью, связанной с обратным потоком данных. Передача состояния реквизитам от родительских компонентов к дочерним компонентам может..

5 обязательных элементов современного инструмента конвейера данных
В цифровом мире предприятия используют конвейеры данных для перемещения, преобразования и хранения огромных объемов данных. Эти конвейеры составляют основу бизнес-аналитики и играют..

Случай использования npm3 вместо npm2 для разработки библиотеки
Некоторое время назад я создал библиотеку на NodeJS, чтобы упростить рендеринг на стороне сервера и клиента. Он использует React и React Router для отображения соответствующего HTML на веб-сайте...