python:tkinter 树视图颜色未更新
python : tkinter treeview colors are not updating
这是我的第一个post,如果我的格式有误,请原谅,如果需要我会很乐意更改。
我正在使用 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 的文本分别为蓝色、红色、绿色和青色。但是,我只能看到黑色的。
-您在 cmd
中使用的 python 是什么版本 (python -V)
-python 的最后一个版本 (3.7) 似乎有颜色标签的错误
-如果您使用的是 python (3.7),只需安装 python 3.6(它也可能适用于较新的版本)
如前所述,这是 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() 应该可以正常工作。
开始时试试这个
style = ttk.Style()
aktualTheme = style.theme_use()
style.theme_create("dummy", parent=aktualTheme)
style.theme_use("dummy")
示例,使用线程和按钮更新 treeView...使用旋转框更新第 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()
这是我的第一个post,如果我的格式有误,请原谅,如果需要我会很乐意更改。
我正在使用 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 的文本分别为蓝色、红色、绿色和青色。但是,我只能看到黑色的。
-您在 cmd
中使用的 python 是什么版本 (python -V)-python 的最后一个版本 (3.7) 似乎有颜色标签的错误
-如果您使用的是 python (3.7),只需安装 python 3.6(它也可能适用于较新的版本)
如前所述,这是 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() 应该可以正常工作。
开始时试试这个
style = ttk.Style()
aktualTheme = style.theme_use()
style.theme_create("dummy", parent=aktualTheme)
style.theme_use("dummy")
示例,使用线程和按钮更新 treeView...使用旋转框更新第 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()