Tkinter — Как я могу удалить жирный текст и фокус в виджетах со списком?

#python #tkinter #combobox

#python #tkinter #со списком

Вопрос:

Чтобы расфокусировать виджеты со списком, я использую пользовательскую функцию «Defocus», написанную в моем примере:

 from tkinter import *
from tkinter import ttk

def Defocus(event):
    event.widget.master.focus_set()

parent=Tk()
parent.geometry("530x280 370 100")
parent.title("TEST")
parent.configure(background="#f0f0f0")
parent.minsize(485, 280)

SV=StringVar()
SV.set("I hate to see the bold text..")
MenuComboBox=ttk.Combobox(parent, state="readonly", values=("I hate to see the bold text..", "ciao", "hola", "hello"), textvariable=SV, width=50)
MenuComboBox.bind("<FocusIn>", Defocus)
MenuComboBox.place(x=20, y=20)

SV2=StringVar()
SV2.set("I hate to see the bold text..")
MenuComboBox2=ttk.Combobox(parent, state="readonly", values=("I hate to see the bold text..", "ciao", "hola", "hello"), textvariable=SV2, width=50)
MenuComboBox2.bind("<FocusIn>", Defocus)
MenuComboBox2.place(x=20, y=60)

parent.mainloop()
 

это работает, но не совсем, с моей точки зрения, у него «плохое поведение». текст в виджетах со списком стал жирным, и мне это не нравится (см. Мой прикрепленный GIF). У меня два вопроса:

  1. как я могу улучшить свою пользовательскую функцию «Расфокусировки», чтобы убрать «жирный вариант» в виджетах со списком?
  2. есть ли способ изменить стиль виджетов со списком по умолчанию, чтобы удалить параметры фокусировки и жирного текста? таким образом, я могу избежать использования моей пользовательской функции каждый раз, когда мне приходится использовать виджет со списком.

введите описание изображения здесь

Ответ №1:

Combobox использует жирный текст всякий раз, когда его запись сфокусирована. Таким образом, решением было бы использовать другую запись и сместить фокус на нее.
Итак, я создал фиктивную запись с именем dump .этот дамп скрыт place_forget() .
Как сместить фокус? для этого выполняйте эти шаги всякий раз, когда выбран элемент <<ComboboxSelected>>

  • сфокусируйте корневое окно ( parent.focus() )
  • введите что-нибудь в entry ( set() )
  • сфокусируйте его ( focus() )
  • выберите его select_range()

Чтобы узнать разницу, я включил обычный список со списком MenuComboBox2

 from tkinter.ttk import Combobox
from tkinter import *
class CBox(Frame):
    def __init__(self,parent,variable):
        super().__init__(parent)
        self.SV=variable
        self.Box=Combobox(self,state="readonly", values=("I hate to see the bold text..", "ciao", "hola", "hello"), textvariable=self.SV, width=50)
        self.Box.bind('<<ComboboxSelected>>',self.doThat)
        self.fvar=StringVar()
        self.fake=Entry(self,text='test',textvariable=self.fvar)
        self.arrange()
    def arrange(self):
        self.Box.pack()
        self.fake.pack()
        self.fake.pack_forget()
    def doThat(self,*args):
        self.focus()
        self.fvar.set('Hello')
        self.fake.focus()
        self.fake.select_range(0,'end')
root=Tk()
SV=StringVar()
def Defocus(event):
    event.widget.master.focus_set()
diff=Combobox(root,state="readonly", values=("I hate to see the bold text..", "ciao", "hola", "hello"), width=50)
diff.pack()
diff.bind("<FocusIn>", Defocus)
a=CBox(root,SV)
a.pack()

root.mainloop()
 

Редактировать: теперь это не зависит от родительского элемента. (см. CBox только это)

Комментарии:

1. это обходной путь, но .. он работает, спасибо RahulARange! в моем реальном программном обеспечении у меня много окон верхнего уровня. итак, чтобы улучшить вашу selected пользовательскую функцию, я предлагаю заменить parent.focus() инструкцию event.widget.master.focus_set() и добавить event опцию, в противном случае всякий раз, когда пользователь использует виджет со списком в окне верхнего уровня, он будет перенаправлен на родительский, и это не очень хорошее поведение.

2. @TurboC теперь я создал пользовательский класс, который не зависит от родительского виджета для фокусировки