【问题标题】:Python3 tkinter analog gaugePython3 tkinter 模拟量规
【发布时间】:2017-10-17 11:26:42
【问题描述】:

我正在尝试为我用 Python 3.6 编写的 tkinter/ttk GUI 使用模拟量规。

我想显示伏特和 psi 值。

到目前为止,我的研究使我找到了this (linuxcnc/pyvcp?)、this (perl/tk) 和 this (tk)。

我有没有机会整合这三个,或者我应该尝试使用tkinter.Canvas 来实现我自己的仪表?

【问题讨论】:

    标签: python python-3.x user-interface tkinter


    【解决方案1】:

    我创建了一个名为 tk_tools 的包,其中包含其中一个模拟仪表。

    pip install tk_tools

    来源:https://github.com/slightlynybbled/tk_tools

    文档:https://tk-tools.readthedocs.io/en/latest/docs/widgets/#rotaryscale

    您正在寻找RotaryScale 小部件。在examples/rotary_scale.py 中可以找到一个使用示例。简短版:

    import tkinter as tk
    import tk_tools
    
    root = tk.Tk()
    
    p = tk_tools.RotaryScale(root, max_value=100.0, unit='psi')
    p.grid()
    
    p.set_value(32.7)
    
    root.mainloop()
    

    【讨论】:

    • 看起来很棒!背景只是一个png,所以我可以改变它。我一定会试试这个。
    • 好交易。我发现我周围的人(在labview中编程)有几个我没有的用户界面元素,所以这是其中一些元素的部分根源。如果您想出更好的背景图片,请添加它并提出拉取请求!用户没有理由不能指定他们想要的背景。
    【解决方案2】:

    我已经用python翻译了第三个:

    import tkinter as tk
    from math import pi, cos, sin
    
    
    class Meter(tk.Frame):
        def __init__(self, master=None, **kw):
            tk.Frame.__init__(self, master, **kw)
    
            self.meter = []
            self.angle = []
            self.var = tk.IntVar(self, 0)
    
            self.canvas = tk.Canvas(self, width=200, height=110,
                                    borderwidth=2, relief='sunken',
                                    bg='white')
            self.scale = tk.Scale(self, orient='horizontal', from_=0, to=100, variable=self.var)
    
            for j, i in enumerate(range(0, 100, 5)):
                self.meter.append(self.canvas.create_line(100, 100, 10, 100,
                                                          fill='grey%i' % i,
                                                          width=3,
                                                          arrow='last'))
                self.angle.append(0)
                self.canvas.lower(self.meter[j])
                self.updateMeterLine(0.2, j)
    
            self.canvas.create_arc(10, 10, 190, 190, extent=108, start=36,
                                   style='arc', outline='red')
    
            self.canvas.pack(fill='both')
            self.scale.pack()
    
            self.var.trace_add('write', self.updateMeter)  # if this line raises an error, change it to the old way of adding a trace: self.var.trace('w', self.updateMeter)
            self.updateMeterTimer()
    
        def updateMeterLine(self, a, l=0):
            """Draw a meter line (and recurse for lighter ones...)"""
            oldangle = self.angle[l]
            self.angle[l] = a
            x = 100 - 90 * cos(a * pi)
            y = 100 - 90 * sin(a * pi)
            self.canvas.coords(self.meter[l], 100, 100, x, y)
            l += 1
            if l < len(self.meter):
                self.updateMeterLine(oldangle, l)
    
        def updateMeter(self, name1, name2, op):
            """Convert variable to angle on trace"""
            mini = self.scale.cget('from')
            maxi = self.scale.cget('to')
            pos = (self.var.get() - mini) / (maxi - mini)
            self.updateMeterLine(pos * 0.6 + 0.2)
    
        def updateMeterTimer(self):
            """Fade over time"""
            self.var.set(self.var.get())
            self.after(20, self.updateMeterTimer)
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        meter = Meter(root)
        meter.pack()
        root.mainloop()
    

    相同,但没有箭头的褪色效果:

    class Meter(tk.Frame):
        def __init__(self, master=None, **kw):
            tk.Frame.__init__(self, master, **kw)
    
            self.var = tk.IntVar(self, 0)
    
            self.canvas = tk.Canvas(self, width=200, height=110,
                                    borderwidth=2, relief='sunken',
                                    bg='white')
            self.scale = tk.Scale(self, orient='horizontal', from_=0, to=100, variable=self.var)
    
            self.meter = self.canvas.create_line(100, 100, 10, 100,
                                                 fill='black',
                                                 width=3,
                                                 arrow='last')
            self.angle = 0
            self.updateMeterLine(0.2)
    
            self.canvas.create_arc(10, 10, 190, 190, extent=108, start=36,
                                   style='arc', outline='red')
    
            self.canvas.pack(fill='both')
            self.scale.pack()
    
            self.var.trace_add('write', self.updateMeter)  # if this line raises an error, change it to the old way of adding a trace: self.var.trace('w', self.updateMeter)
    
        def updateMeterLine(self, a):
            """Draw a meter line"""
            self.angle = a
            x = 100 - 90 * cos(a * pi)
            y = 100 - 90 * sin(a * pi)
            self.canvas.coords(self.meter, 100, 100, x, y)
    
        def updateMeter(self, name1, name2, op):
            """Convert variable to angle on trace"""
            mini = self.scale.cget('from')
            maxi = self.scale.cget('to')
            pos = (self.var.get() - mini) / (maxi - mini)
            self.updateMeterLine(pos * 0.6 + 0.2)
    

    【讨论】:

    • @NikhilParasha 只需删除updateMeterLine 的递归部分。我已经用没有褪色效果的仪表版本编辑了我的答案。
    • 您好,感谢重播,但此代码中的值不会连续变化。
    • @NikhilParasha 不明白你想做什么。我以为你只是想摆脱多余的褪色箭头。您可能应该提出一个单独的问题,提供更多详细信息。
    猜你喜欢
    • 2021-11-20
    • 2019-06-29
    • 1970-01-01
    • 2015-01-20
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多