Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 图形故障ttk小部件_Python_Tkinter_Ttk_Ttkwidgets - Fatal编程技术网

Python 图形故障ttk小部件

Python 图形故障ttk小部件,python,tkinter,ttk,ttkwidgets,Python,Tkinter,Ttk,Ttkwidgets,这一切都源于这样一个事实:正常的tk.Scale没有被正确地使用(我使用的是一个自定义主题)。 然后我切换到ttk.Scale,但当我更改它时,它没有显示滑块上方的值。 然后我发现了ttkwidget,它似乎可以工作,但存在图形故障。有人有什么想法要解决吗? 代码: 屏幕截图: 另外,有问题的小部件加载速度非常慢 编辑:解决方案在最佳答案的注释中我找到了一种方法来消除ttk.LabeledScale中的故障。我认为问题在于重新绘制整个标签小部件,因此我使用了画布。使用画布,移动文本时,无需重新绘

这一切都源于这样一个事实:正常的
tk.Scale
没有被正确地使用(我使用的是一个自定义主题)。
然后我切换到
ttk.Scale
,但当我更改它时,它没有显示滑块上方的值。
然后我发现了ttkwidget,它似乎可以工作,但存在图形故障。有人有什么想法要解决吗?
代码:
屏幕截图:
另外,有问题的小部件加载速度非常慢


编辑:解决方案在最佳答案的注释中

我找到了一种方法来消除
ttk.LabeledScale
中的故障。我认为问题在于重新绘制整个
标签
小部件,因此我使用了
画布
。使用
画布
,移动文本时,无需重新绘制背景,动画更平滑

下面的代码基于
ttk.LabeledScale
(来自Python 3.9.1,您可以在中找到它)的源代码。但是小部件现在基于
画布
,其中比例和文本添加了
create_window()
ćreate_text()
。我修改了
\uuu init\uuuuuuuuuuu()
\u adjust()
方法,并添加了
\u on\u theme\u change()
方法,该方法在主题更改时调用,以更新画布的样式并调整元素的位置

import tkinter as tk
from tkinter import ttk


class LabeledScale(tk.Canvas):

    def __init__(self, master=None, variable=None, from_=0, to=10, **kw):
        self._label_top = kw.pop('compound', 'top') == 'top'

        tk.Canvas.__init__(self, master, **kw)
        self._variable = variable or tk.IntVar(master)
        self._variable.set(from_)
        self._last_valid = from_

        # use style to set the Canvas background color
        self._style = ttk.Style(self)
        self.configure(bg=self._style.lookup('Horizontal.TScale', 'background'))
        # create the scale
        self.scale = ttk.Scale(self, variable=self._variable, from_=from_, to=to)
        self.scale.bind('<<RangeChanged>>', self._adjust)

        # put scale in canvas
        self._scale = self.create_window(0, 0, window=self.scale, anchor='nw')
        # put label in canvas (the position will be updated later)
        self._label = self.create_text(0, 0, text=self._variable.get(),
                                       fill=self._style.lookup('TLabel', 'foreground'),
                                       anchor='s' if self._label_top else 'n')
        # adjust canvas height to fit the whole content
        bbox = self.bbox(self._label)
        self.configure(width=self.scale.winfo_reqwidth(),
                       height=self.scale.winfo_reqheight() + bbox[3] - bbox[1])
        # bindings and trace to update the label
        self.__tracecb = self._variable.trace_variable('w', self._adjust)
        self.bind('<Configure>', self._adjust)
        self.bind('<Map>', self._adjust)
        # update sizes, positions and appearances on theme change
        self.bind('<<ThemeChanged>>', self._on_theme_change)

    def destroy(self):
        """Destroy this widget and possibly its associated variable."""
        try:
            self._variable.trace_vdelete('w', self.__tracecb)
        except AttributeError:
            pass
        else:
            del self._variable
        super().destroy()
        self.label = None
        self.scale = None

    def _on_theme_change(self, *args):
        """Update position and appearance on theme change."""
        def adjust_height():
            bbox = self.bbox(self._label)
            self.configure(height=self.scale.winfo_reqheight() + bbox[3] - bbox[1])

        self.configure(bg=self._style.lookup('Horizontal.TScale', 'background'))
        self.itemconfigure(self._label, fill=self._style.lookup('TLabel', 'foreground'))
        self._adjust()
        self.after_idle(adjust_height)

    def _adjust(self, *args):
        """Adjust the label position according to the scale."""
        def adjust_label():
            self.update_idletasks() # "force" scale redraw
            x, y = self.scale.coords()
            if self._label_top:
                y = 0
            else:
                y = self.scale.winfo_reqheight()
            # avoid that the label goes off the canvas
            bbox = self.bbox(self._label)
            x = min(max(x, 0), self.winfo_width() - (bbox[2] - bbox[0])/2)
            self.coords(self._label, x, y)  # move label
            self.configure(scrollregion=self.bbox('all'))
            self.yview_moveto(0)  # make sure everything is visible

        self.itemconfigure(self._scale, width=self.winfo_width())
        from_ = ttk._to_number(self.scale['from'])
        to = ttk._to_number(self.scale['to'])
        if to < from_:
            from_, to = to, from_
        newval = self._variable.get()
        if not from_ <= newval <= to:
            # value outside range, set value back to the last valid one
            self.value = self._last_valid
            return

        self._last_valid = newval
        self.itemconfigure(self._label, text=newval)
        self.after_idle(adjust_label)

    @property
    def value(self):
        """Return current scale value."""
        return self._variable.get()

    @value.setter
    def value(self, val):
        """Set new scale value."""
        self._variable.set(val)

root = tk.Tk()
style = ttk.Style(root)
style.theme_use('alt')

scale = LabeledScale(root, from_=0, to=100, compound='bottom')
scale.pack(expand=True, fill='x')

root.mainloop()
将tkinter作为tk导入
从tkinter导入ttk
类标签缩放(tk.Canvas):
def uuu init uuuuu(self,master=None,variable=None,from=0,to=10,**kw):
自我标签\u top=kw.pop('composite','top')=='top'
tk.Canvas.\uuuuuu初始值\uuuuuuuuuuuuuuuuuuuuu(自,主,**kw)
self.\u variable=变量或tk.IntVar(主)
self.\u变量.set(来自)
self.\u last\u valid=from_
#使用样式设置画布背景色
self.\u style=ttk.style(self)
self.configure(bg=self.\u-style.lookup('Horizontal.TScale','background'))
#创建比例
self.scale=ttk.scale(self,variable=self.\u变量,from=from,to=to)
自缩放绑定(“”,自调整)
#把天平放在画布上
self.\u scale=self.create\u window(0,0,window=self.scale,anchor='nw')
#将标签放入画布(稍后将更新位置)
self.\u label=self.create\u text(0,0,text=self.\u variable.get(),
fill=self.\u style.lookup('TLabel','front'),
anchor='s'如果是self.\u label\u top else'n')
#调整画布高度以适合整个内容
bbox=self.bbox(self.\u标签)
self.configure(width=self.scale.winfo_reqwidth(),
高度=self.scale.winfo_reqheight()+bbox[3]-bbox[1])
#绑定和跟踪以更新标签
self.\u tracebc=self.\u变量。跟踪变量('w',self.\u调整)
自我绑定(“”,自我调整)
自我绑定(“”,自我调整)
#更新主题更改时的尺寸、位置和外观
自我绑定(“”,自我主题改变)
def销毁(自我):
“”“销毁此小部件及其相关变量。”“”
尝试:
self.\u变量.trace\u vdelete('w',self.\u traceb)
除属性错误外:
通过
其他:
del self.\u变量
super().destroy()
self.label=None
self.scale=无
定义主题更改(self,*args):
“”“更新主题更改时的位置和外观。”“”
def调整高度()
bbox=self.bbox(self.\u标签)
self.configure(height=self.scale.winfo_reqheight()+bbox[3]-bbox[1])
self.configure(bg=self.\u-style.lookup('Horizontal.TScale','background'))
self.itemconfigure(self.\u label,fill=self.\u style.lookup('TLabel','front'))
自我调整
自空转后(调整高度)
def_调整(自,*参数):
“”“根据刻度调整标签位置。”“”
def调整_标签():
self.update_idletasks()
x、 y=self.scale.coords()
如果是自贴标签,则为顶部:
y=0
其他:
y=self.scale.winfo_reqheight()
#避免标签从画布上脱落
bbox=self.bbox(self.\u标签)
x=min(max(x,0),self.winfo_width()-(bbox[2]-bbox[0])/2)
self.coords(self._标签,x,y)#移动标签
configure(scrollregion=self.bbox('all'))
self.yview_moveto(0)#确保所有内容都可见
self.itemconfigure(self.\u scale,width=self.winfo\u width())
from=ttk.\u到_编号(自刻度['from'])
to=ttk.\u至\u编号(自刻度['to'])
如果to如果不是从uu,我们应该假设什么是
ttkwidget
?它是从
tkinter
图书馆来的吗?很抱歉误解了。问题是由
ttkwidgets
中的小部件引起的,对吗?这个问题实际上在这里不太有效,因为错误不是由标准
tkinter
小部件引起的。你可能应该在上问同样的问题,这样开发者就不能直接与你联系。请不要链接到其他网站的代码。花点时间在你的问题中直接嵌入a。谢谢你,但我终于想出了如何创造我想要的。在
ttkwidgets.Tickscale
中,我设置了
digits=0
,现在下面的标签消失了,滑动的值是一个整数