Стрелки полосы прокрутки Python Tkinter выделены серым цветом

У меня небольшая проблема с полосами прокрутки. Функционально все работает нормально. Появляются полосы прокрутки, реагируют на вставку в текстовые виджеты и работает прокрутка. Но сразу после запуска приложения кнопки со стрелками на всех полосах прокрутки отображаются серым цветом, пока я не изменю размер окна приложения. Есть ли что-то принципиально неправильное в моих кадрах в настройках сетки? Я разделил на четверти: Верхний левый (UL), Верхний правый (UR), Нижний левый (LL), Нижний правый (LR).

import Tkinter
from Tkinter import *

class findhash_tk(Tkinter.Tk):

    def __init__(self, parent):

        Tkinter.Tk.__init__(self, parent)
        self.parent = parent
        self.initialize()

    def initialize(self):

        self.frameUL = Tkinter.LabelFrame(self, text="Upper left")   
        self.frameUL.grid(row=0, column=0, sticky=W+E+N+S, padx=2, pady=2)

        self.frameUR = Tkinter.LabelFrame(self, text="Upper right")   
        self.frameUR.grid(row=0, column=1, sticky=W+E+N+S, padx=2, pady=2)

        self.frameLL = Tkinter.LabelFrame(self, text="Lower left")   
        self.frameLL.grid(row=1, column=0, sticky=W+E+N+S, padx=2, pady=2)

        self.frameLR = Tkinter.LabelFrame(self, text="Lower right")   
        self.frameLR.grid(row=1, column=1, sticky=W+E+N+S, padx=2, pady=2)

        self.scrollbarUR = Tkinter.Scrollbar(self.frameUR, orient='vertical')
        self.scrollbarUR.grid(row=0, column=1, sticky=N+S)     

        self.textBoxUR = Tkinter.Text(self.frameUR)
        self.textBoxUR.config(yscrollcommand=self.scrollbarUR.set)
        self.textBoxUR.grid(row=0, column=0, sticky=W+E+N+S)

        self.scrollbarUR.config(command=self.textBoxUR.yview)

        self.scrollbarLLV = Tkinter.Scrollbar(self.frameLL, orient='vertical')
        self.scrollbarLLV.grid(row=0, column=1, sticky=N+S)

        self.scrollbarLLH = Tkinter.Scrollbar(self.frameLL, orient='horizontal')
        self.scrollbarLLH.grid(row=1, column=0, sticky=W+E)

        self.textBoxLL = Tkinter.Text(self.frameLL)
        self.textBoxLL.config(wrap="none", yscrollcommand=self.scrollbarLLV.set, xscrollcommand=self.scrollbarLLH.set)
        self.textBoxLL.grid(row=0, column=0, sticky=W+E+N+S)

        self.scrollbarLLV.config(command=self.textBoxLL.yview)
        self.scrollbarLLH.config(command=self.textBoxLL.xview)

        self.scrollbarLRV = Tkinter.Scrollbar(self.frameLR, orient='vertical')
        self.scrollbarLRV.grid(row=0, column=1, sticky=N+S)

        self.scrollbarLRH = Tkinter.Scrollbar(self.frameLR, orient='horizontal')
        self.scrollbarLRH.grid(row=1, column=0, sticky=W+E)

        self.textBoxLR = Tkinter.Text(self.frameLR)
        self.textBoxLR.config(wrap="none", yscrollcommand=self.scrollbarLRV.set, xscrollcommand=self.scrollbarLRH.set)
        self.textBoxLR.grid(row=0, column=0, sticky=W+E+N+S)

        self.scrollbarLRV.config(command=self.textBoxLR.yview)
        self.scrollbarLRH.config(command=self.textBoxLR.xview)

        for x in range(50): 
            self.textBoxUR.insert(END, str(x) + "\n")

        for x in range(50): 
            self.textBoxLL.insert(END, str(x) + "\n")

        for x in range(50): 
            self.textBoxLR.insert(END, str(x) + "\n")

if __name__ == "__main__":
    app = findhash_tk(None)
    app.title('Test App')
    app.mainloop()

Исходное состояние графического интерфейса


person ManuMeadow    schedule 02.11.2016    source источник


Ответы (2)


Вставьте self.update() после:

self.textBoxUR.grid(row=0, column=0, sticky=W+E+N+S)

Как ни странно, дальше вниз работать не будет (некоторые полосы прокрутки будут выделены серым цветом, или левая нижняя горизонталь будет окрашена, чего не должно быть). Это исправит это для вас, но это выглядит как ошибка.

EDIT Как упоминает OP, это непоследовательно и в любом случае странно. Обходной путь после инициализации():

self.wm_geometry("+4000+4000")
self.after(500,lambda:self.wm_geometry("+10+10"))

Это грязно, но вызывает обновление в окнах, помещая окно за пределы экрана (если ваш экран больше 4000 пикселей, ничего себе, но вы можете увеличить), и через полсекунды перемещает его обратно. Это похоже на странную проблему, и в Linux этого не происходит (хотя цвет там всегда сероватый).

person kabanus    schedule 02.11.2016
comment
Я попытался поставить self.update() ниже, но это не сработало. Размещение его там, где вы предлагаете, по-прежнему оставляет стрелки горизонтальной полосы прокрутки LL серыми. - person ManuMeadow; 02.11.2016
comment
Обе горизонтальные полосы прокрутки (это внизу, верно?) должны быть серыми - прокручивать нечего. Вы хотите изменить это поведение? - person kabanus; 02.11.2016
comment
Нет, совсем нет. Но это непоследовательно, с вашим решением все стрелки показаны черными, а также нижняя правая горизонтальная полоса. Только нижний левый остается серым. - person ManuMeadow; 02.11.2016
comment
В Linux нет изменения цвета, я думаю, что это может быть связано с Windows. Я отредактирую обходной путь в решении, но отправлю сообщение об ошибке команде tkinter. - person kabanus; 03.11.2016
comment
Большое спасибо за твою помощь! - person ManuMeadow; 03.11.2016

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

from tkinter import *

if __name__ == "__main__":
    root = Tk()

    ###

    badframe = Frame(root)
    badframe.grid(row=0, column=0)

    badtext = Text(badframe)
    badtext.grid(row=0, column=0)

    badscrollbar = Scrollbar(badframe, command=badtext.yview)
    badscrollbar.grid(row=0, column=1, sticky=N+S)     

    badtext.config(yscrollcommand=badscrollbar.set)

    def fillbad():
        global badtext
        for i in range(50):
            badtext.insert(END, str(i) + "\n")

    badfillbutton = Button(root, command=fillbad, text="fill")
    badfillbutton.grid(row=1, column=0)

    def clearbad():
        global badtext
        badtext.delete(1.0, END)

    badclearbutton = Button(root, command=clearbad, text="clear")
    badclearbutton.grid(row=2, column=0)

    ###

    def fixyscrollcommand(lo, hi):
        global noyscroll, goodframe, goodscrollbar, goodtext

        start = float(lo)
        end = float(hi)

        # weird Windows bug
        if noyscroll != ((end - start) >= 1.0):
            goodscrollbar.destroy()
            goodscrollbar = Scrollbar(goodframe, command=goodtext.yview)
            goodscrollbar.grid(row=0, column=1, sticky=N+S)

        goodscrollbar.set(lo, hi)

        noyscroll = False
        if (end - start) >= 1.0:
            noyscroll = True

    goodframe = Frame(root)
    goodframe.grid(row=0, column=1)

    goodtext = Text(goodframe, yscrollcommand=fixyscrollcommand)
    goodtext.grid(row=0, column=0)

    goodscrollbar = Scrollbar(goodframe, command=goodtext.yview)
    goodscrollbar.grid(row=0, column=1, sticky=N+S)
    noyscroll = True

    def fillgood():
        global goodtext
        for i in range(50):
            goodtext.insert(END, str(i) + "\n")

    goodbutton = Button(root, command=fillgood, text="fill")
    goodbutton.grid(row=1, column=1)

    def cleargood():
        global goodtext
        goodtext.delete(1.0, END)

    goodclearbutton = Button(root, command=cleargood, text="clear")
    goodclearbutton.grid(row=2, column=1)

    ###

    mainloop()
person Jason Brown    schedule 04.12.2019