【问题标题】:python : tkinter treeview colors are not updatingpython:tkinter treeview 颜色没有更新
【发布时间】:2019-05-27 18:37:59
【问题描述】:

这是我的第一篇文章,如果我在格式上有错误,请原谅,如果需要,我很乐意更改。

我正在使用 Tkinter 创建一个用于科学数据分析的界面。对于分子列表,可以在单独的图中表示四个。另一方面,我使用 Treeview 来显示所有分子的一些数字。 (不仅仅是显示的)当树视图行是关于显示的图时,我希望该行的文本是相同的颜色。

对于每个显示的图形,我在代表它的行上放置一个不同的标签,然后使用标签方法将前景色更改为图形的颜色。

以前的代码可以正常工作,但现在它已经停止工作,而我的代码没有任何更改。使用标签设置前景色不会改变颜色。几行之后,我也使用该方法将行更改为粗体,并且效果很好。

我设法确认代码行被正确读取:如果我将颜色设置为无法识别的值,则在按预期执行时会出现 tkinter 错误。此外,使用一些打印,if/elif 在正确的时刻按预期执行(逻辑测试中没有错误)。

代码在另一台计算机上运行良好,让我相信某些 python 包存在问题。两台电脑的ttk版本相同(0.3.1),我在注意到问题后更新了我的所有模块,以确保它不是一个过时的包。

对计算机所做的唯一更改是删除并重新安装 anaconda 和现在的环境,在使用的环境中添加了 pyinstaller 的安装(使用 pip)(当我在原始环境中安装 pyinstaller 时,我错误地修改了其他重要的软件包,不得不从头开始重新安装 anaconda 以使其再次工作)

我尝试在没有 pyinstaller 模块的情况下创建另一个相同的环境,但得到了相同的结果。

我已经数不清我卸载并重新安装 anaconda 以解决问题的次数了。如果可能的话,我真的不想重新安装它。

我已经隔离了生成树视图对象的界面代码。经过测试,下面的代码片段给了我同样的问题。

import tkinter as tk
from tkinter import ttk
import numpy as np

class Testy():
    def __init__(self, root):

        #Values set in other part of the interface
        self.Classes = ['Molecule1','Molecule2','Molecule3','Molecule4',
                        'Molecule5','Molecule6']
        self.Single_Kinetic_Menu_Var = [tk.StringVar(value = 'Molecule1'), 
                                        tk.StringVar(value = 'Molecule3'),
                                        tk.StringVar(value = 'Molecule4'), 
                                        tk.StringVar(value = 'Molecule5')]
        self.Experiment_Count = np.zeros([len(self.Classes),2])

        #Treeview widget making
        Tree = ttk.Treeview(root)
        Tree.grid(column = 0, row = 0)

        Headings = ('first count','second count')
        Tree['column'] = Headings

        Tree.column("#0", width=100, minwidth=100)
        Tree.heading("#0",text="Class")

        for i in range(len(Headings)) :
            Tree.column(Headings[i])
            Tree.heading(Headings[i], text = Headings[i])

        #Insert all classes and their counts
        Empty = []
        Total = []
        Total = list(Total)
        for Idx, Class in enumerate(self.Classes) :
            Values = []
            if Idx == len(self.Classes)-1 :
                for Number in self.Experiment_Count[Idx,:] :
                    Values.append(str(Number))
                    Empty.append('-')
                    Total.append(0)
            else :
                for Number in self.Experiment_Count[Idx,:] :
                    Values.append(str(Number))
            Values = tuple(Values)

            if Class == self.Single_Kinetic_Menu_Var[0].get() :
                Tree.insert("", Idx, text = Class, values=Values, tags = ('BLUE'))
                Tree.tag_configure('BLUE', foreground = 'blue')
            elif Class == self.Single_Kinetic_Menu_Var[1].get() :
                Tree.insert("", Idx, text = Class, values=Values, tags = ('RED'))
                Tree.tag_configure('RED', foreground = 'red')
            elif Class == self.Single_Kinetic_Menu_Var[2].get() :
                Tree.insert("", Idx, text = Class, values=Values, tags = ('GREEN'))
                Tree.tag_configure('GREEN', foreground = 'green')
            elif Class == self.Single_Kinetic_Menu_Var[3].get() :
                Tree.insert("", Idx, text = Class, values=Values, tags = ('CYAN'))
                Tree.tag_configure('CYAN', foreground = 'cyan')
            else :
                Tree.insert("", Idx, text = Class, values=Values)
        Tree.insert('', len(self.Classes), text = '-', values = tuple(Empty))
        Total = np.sum(self.Experiment_Count[:,:], axis = 0)
        Tree.insert('',len(self.Classes)+1, text = 'TOTAL', values = tuple(Total),
                    tags = ('BOLD'))
        Tree.tag_configure('BOLD', font = ('Calibri', 12, 'bold'))


def main():
    Master = tk.Tk()
    Master.title("interface")


    Testy(Master) 

    Master.mainloop()


if __name__ == '__main__' :
    main()

正如您通过运行代码所看到的,我希望分子 1、3、4 和 5 的文本分别为蓝色、红色、绿色和青色。但是,我只能看到它们是黑色的。

【问题讨论】:

  • 这段代码给了我你想要的输出,所以这段代码没有问题
  • 感谢您的反馈,但这正是我的问题。代码很好,但是有些东西可以阻止彩色显示,因为我只能在我的电脑上看到它是黑色的。我想指出导致此问题的原因,以便制作可以分发并适用于所有人的可靠代码。
  • 请问您的 python 版本?
  • Python 3.6.3 |Anaconda 自定义(64 位)| (默认,2017 年 10 月 15 日,03:27:45)[MSC v.1900 64 位 (AMD64)] 在 win32 上
  • @Chetan Vashisth 我的错,从错误的计算机上获取了 python 版本,实际版本是 Python 3.7.3。我相信版本中提到问题的答案和cmets是正确的。

标签: python-3.x tkinter colors treeview


【解决方案1】:

如前所述,这是 tkinter 库 > 8.6.8 的一个已知问题。此版本的 tkinter 预装了较新版本的 Python (> 3.7)。

已在此处提出了解决此问题的方法: https://core.tcl-lang.org/tk/tktview?name=509cafafae

定义过滤参数的函数

def fixed_map(option):
    # Returns the style map for 'option' with any styles starting with
    # ("!disabled", "!selected", ...) filtered out

    # style.map() returns an empty list for missing options, so this should
    # be future-safe
    return [elm for elm in style.map("Treeview", query_opt=option)
            if elm[:2] != ("!disabled", "!selected")]

使用新函数映射样式

style = ttk.Style()
style.map("Treeview", 
          foreground=fixed_map("foreground"),
          background=fixed_map("background"))

这样,tag_configure() 应该可以按预期工作。

【讨论】:

【解决方案2】:

-你在cmd中使用的是什么版本的python(python -V)

-python 的最新版本(3.7)似乎对颜色标签有错误

-如果您使用的是 python (3.7),只需安装 python 3.6(它也可能适用于较新版本)

【讨论】:

  • 这确实是Python版的,非常感谢。如果有人遇到同样的问题,有关更多信息,代码在 3.7.1 中运行良好,但我在 3.7.3 版本中遇到问题
  • 这个答案已经有一年多了。不知道能不能更新?
  • 看看下面的回复有更多细节!!
【解决方案3】:

一开始就试试这个

style = ttk.Style()
aktualTheme = style.theme_use()
style.theme_create("dummy", parent=aktualTheme)
style.theme_use("dummy")

例如,使用线程和按钮更新 treeView... 使用 spinbox 更新第 n 行......

from tkinter import *
from tkinter import ttk,messagebox
import time
import threading

def thd():
    time.sleep(4)
    pos = int(xs.get())
    stg= "Row"
    pf = "updated"
    tv.item(pos, text='', values=(stg,pf),  tags = ('fail',))
    
def helloCallBack():
    thd()

ws = Tk()
ws.title('Vik')
ws.geometry('400x300')
ws['bg']='#fb0'

style = ttk.Style()
aktualTheme = style.theme_use()
style.theme_create("dummy", parent=aktualTheme)
style.theme_use("dummy")

tv = ttk.Treeview(ws)
tv['columns']=('Stage', 'Status', )
tv.column('#0', width=0, stretch=NO)
tv.column('Stage', anchor=CENTER, width=80)
tv.column('Status', anchor=CENTER, width=80)
# tv.column('Badge', anchor=CENTER, width=80)
tv.heading('#0', text='', anchor=CENTER)
tv.heading('Stage', text='Id', anchor=CENTER)
tv.heading('Status', text='rank', anchor=CENTER)
# tv.heading('Badge', text='Badge', anchor=CENTER)

tv.insert(parent='', index=0, iid=0, text='', values=('1','1'), tags = 'pass')
tv.insert(parent='', index=1, iid=1, text='', values=('2','2'), tags = 'pass')
tv.insert(parent='', index=2, iid=2, text='', values=('3','3'), tags = 'pass')
tv.insert(parent='', index=3, iid=3, text='', values=('4','4'), tags = 'pass')
tv.insert(parent='', index=4, iid=4, text='', values=('5','5'), tags = 'pass')
tv.tag_configure('fail', foreground='red', background='white', font=('Calibri', 11))
tv.tag_configure('pass', foreground='green', background='white',font=('Calibri', 9))

tv.pack()
xs = Spinbox(ws, from_=0, to=4)
xs.pack()
global posi 
posi = int(xs.get())
ins_button = ttk.Button(
    ws,
    text='Insert',
    command=helloCallBack
)

ins_button.pack(
    ipadx=3,
    ipady=3,
    expand=True
)

exit_button = ttk.Button(
    ws,
    text='Exit',
    command=lambda: ws.quit()
)

exit_button.pack(
    ipadx=3,
    ipady=3,
    expand=True
)

th = threading.Thread(target=thd)
th.start()
ws.mainloop()


  

【讨论】:

    猜你喜欢
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多