- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我开始构建 Tkinter 应用程序,最初使用的是 matplotlib 的 Figure
和 figure.add_subplot
。有了它,一切都完美无缺。对于更多自定义,我现在想移动到 pyplot
和 subplot2grid
,但在这样做时,我的所有 tkinter 变量突然停止工作。
在我的 MWE 中,变量 gArrChoice
跟踪哪个单选按钮被选中并且应该默认为第一个选项。基于此选项,图形应绘制一条悬停在 0.1 附近的线。如果选择了第二个选项,图表应该会变为在 5 左右徘徊。图表每 2.5 秒自动更新一次。如果您注释掉“Working”下方的 3 行并改为使用 3 行“Not Working”,则变量的默认设置将停止工作并且在单选按钮之间切换将不再起作用。在 animate 函数内部声明 a 不会改变问题。
如何将 plt 与 Tkinter 一起使用而不破坏我的变量?
MWE:
import tkinter as tk
import matplotlib
matplotlib.use("TkAgg") #make sure you use the tkinter backend
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.animation as animation
import numpy as np
gArrChoice = 0
#Working - using Figure and add_subplot
from matplotlib.figure import Figure
f = Figure()
a = f.add_subplot(121)
#Not Working - using plt and subplot2grid
# from matplotlib import pyplot as plt
# f = plt.figure()
# a = plt.subplot2grid((10, 7), (0, 0), rowspan=10, colspan=5)
class BatSimGUI(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
frame = StartPage(container,self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#Set defaults for global variable
global gArrChoice
gArrChoice = tk.IntVar()
gArrChoice.set(1)
radioArr1 = tk.Radiobutton(self, variable=gArrChoice, text="Exponential", value=1, command= lambda: print(gArrChoice.get()))
radioArr1.grid(row=2, column=0)
radioArr2 = tk.Radiobutton(self, variable=gArrChoice, text="Normal", value=2, command= lambda: print(gArrChoice.get()))
radioArr2.grid(row=3, column=0)
#Add Canvas
canvas = FigureCanvasTkAgg(f, self)
canvas.draw()
canvas.get_tk_widget().grid(row=1, column=1, columnspan=7, rowspan = 10)
def animate(i):
global gArrChoice
if gArrChoice.get() == 1:
lam = np.random.exponential(scale=.1, size = 100).reshape(-1,1)
else:
lam = np.random.normal(loc=5, scale=1, size = 100).reshape(-1,1)
a.clear()
a.step(list(range(100)), list(lam))
#Actually run the interface
app = BatSimGUI()
app.geometry("800x600")
ani = animation.FuncAnimation(f, animate, interval = 2500)
app.mainloop()
最佳答案
我认为 OO 方法会更好。
见下文,我使用线程和队列来管理绘图动画,您甚至可以设置时间间隔并动态更改图形类型
干得不错,很有趣
#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import threading
import queue
import time
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
try:
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk as nav_tool
except:
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg as nav_tool
import numpy as np
class MyThread(threading.Thread):
def __init__(self, queue, which, ops, interval):
threading.Thread.__init__(self)
self.queue = queue
self.check = True
self.which = which
self.ops = ops
self.interval = interval
def stop(self):
self.check = False
def run(self):
while self.check:
if self.which.get() ==0:
lam = np.random.exponential(scale=.1, size = 100).reshape(-1,1)
else:
lam = np.random.normal(loc=5, scale=1, size = 100).reshape(-1,1)
time.sleep(self.interval.get())
args = (lam, self.ops[self.which.get()])
self.queue.put(args)
else:
args = (None, "I'm stopped")
self.queue.put(args)
class Main(ttk.Frame):
def __init__(self, parent):
super().__init__()
self.parent = parent
self.which = tk.IntVar()
self.interval = tk.DoubleVar()
self.queue = queue.Queue()
self.my_thread = None
self.init_ui()
def init_ui(self):
f = ttk.Frame()
#create graph!
self.fig = Figure()
self.fig.suptitle("Hello Matplotlib", fontsize=16)
self.a = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, f)
toolbar = nav_tool(self.canvas, f)
toolbar.update()
self.canvas._tkcanvas.pack(fill=tk.BOTH, expand=1)
w = ttk.Frame()
ttk.Button(w, text="Animate", command=self.launch_thread).pack()
ttk.Button(w, text="Stop", command=self.stop_thread).pack()
ttk.Button(w, text="Close", command=self.on_close).pack()
self.ops = ('Exponential','Normal',)
self.get_radio_buttons(w,'Choice', self.ops, self.which,self.on_choice_plot).pack(side=tk.TOP, fill=tk.Y, expand=0)
ttk.Label(w, text = "Interval").pack()
tk.Spinbox(w,
bg='white',
from_=1.0, to=5.0,increment=0.5,
justify=tk.CENTER,
width=8,
wrap=False,
insertwidth=1,
textvariable=self.interval).pack(anchor=tk.CENTER)
w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
f.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
def launch_thread(self):
self.on_choice_plot()
def stop_thread(self):
if self.my_thread is not None:
if(threading.active_count()!=0):
self.my_thread.stop()
def on_choice_plot(self, evt=None):
if self.my_thread is not None:
if (threading.active_count()!=0):
self.my_thread.stop()
self.my_thread = MyThread(self.queue,self.which, self.ops, self.interval)
self.my_thread.start()
self.periodiccall()
def periodiccall(self):
self.checkqueue()
if self.my_thread.is_alive():
self.after(1, self.periodiccall)
else:
pass
def checkqueue(self):
while self.queue.qsize():
try:
args = self.queue.get()
self.a.clear()
self.a.grid(True)
if args[0] is not None:
self.a.step(list(range(100)), list(args[0]))
self.a.set_title(args[1], weight='bold',loc='left')
else:
self.a.set_title(args[1], weight='bold',loc='left')
self.canvas.draw()
except queue.Empty:
pass
def get_radio_buttons(self, container, text, ops, v, callback=None):
w = ttk.LabelFrame(container, text=text,)
for index, text in enumerate(ops):
ttk.Radiobutton(w,
text=text,
variable=v,
command=callback,
value=index,).pack(anchor=tk.W)
return w
def on_close(self):
if self.my_thread is not None:
if(threading.active_count()!=0):
self.my_thread.stop()
self.parent.on_exit()
class App(tk.Tk):
"""Start here"""
def __init__(self):
super().__init__()
self.protocol("WM_DELETE_WINDOW", self.on_exit)
self.set_title()
self.set_style()
Main(self)
def set_style(self):
self.style = ttk.Style()
#('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
self.style.theme_use("clam")
def set_title(self):
s = "{0}".format('Simple App')
self.title(s)
def on_exit(self):
"""Close all"""
if messagebox.askokcancel("Simple App", "Do you want to quit?", parent=self):
self.destroy()
if __name__ == '__main__':
app = App()
app.mainloop()
关于python - Tkinter plt.figure() 不绘制,但 Figure() 绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55542813/
在 How to make a Tkinter window jump to the front? 中提出的问题之后的一个问题 我希望有一个顶层窗口(我用它来导航我的其他主窗口)总是在前面。但我希望它
有没有办法在 Tkinter 中保持小部件(特别是图像)的堆叠顺序一致?例如,我可能在 Canvas 上的同一位置有两个矩形、两个三角形和一个圆。圆圈移动到最后一次点击鼠标的地方,但我总是希望它被绘制
这是一个简单的 GUI 程序,用于创建 5x16 按钮矩阵。 from tkinter import * root = Tk() button = [[0 for x in range(16)] fo
有一个错误:“AttributeError: module 'tkinter' has no attribute 'messagebox'” 即使 import tkinter 一开始就已经给出了,为
我知道 menu.tk_popup() 可用于在特定坐标处打开上下文菜单,但也不知道如何从中打开子菜单,如果这有意义的话。这是我编写的代码: import tkinter as tk root = t
我正在尝试在禁用自动换行和水平滚动条的文本窗口中书写,如下所示: root = Toplevel() root.geometry("%dx%d+0+0" % (350,400)) af=Frame(r
已经将文本变量分配给小部件后,如何将其删除? widget.config(textvariable=None)只是不工作。在谷歌或这里找不到任何东西。 最佳答案 将您的变量分配给一个空字符串以实现此目
Jython 支持 Tkinter 吗?如果我用 Python 编写一个程序并放一个 使用 Tkinter 的 GUI 前端,做同样的事情有多难 Jython 中的程序?或者对于 Jython GUI
因此,我尝试创建一个 tkinter 窗口,显示当前时间和日期以及自定义短语。不过,我遇到的问题是,我似乎无法在第二天刷新日期。 我可以传递截至运行代码时的当前日期,但之后它变为静态。 这是我目前的程
我的理解是在初始化 __init__ 中的所有框架和小部件之后方法,tkinter 窗口会调整大小以适合所有这些组件。 我想将窗口的初始化大小设置为其最小大小。我希望能够最大化并放大窗口,但我从不希望
此代码仅水平居中,如何使进度条也垂直居中? import Tkinter import ttk root = Tkinter.Tk() root.geometry("=500x500") root.p
使用 Python 2.7 和 Tkinter 模块,我创建了一个菜单按钮并为其分配了一个菜单。现在每次我在特定位置发布菜单时,菜单的宽度都会根据字符数自动设置。有没有办法在菜单小部件中设置静态宽度?
我想将我的 tkinter 应用程序的主题更改为 clam。 代码是什么,我把它放在哪里?我试过了: from tkinter import * from tkinter.ttk import * s
我有以下代码: from Tkinter import * from urllib import urlretrieve import webbrowser import ttk def get_la
我知道,如果我将滚动条控制的框架绑定(bind)到函数 ( onFrameConfigure ),您可以获得滚动条位置,如下所示:self.calendar_frame.bind("", self.o
许多网站都说菜单小部件有一个选项“字体”,但我一直无法设置它。系统是在 Windows 8.1 中运行的 Python 3.5。脚本开始: 从 tkinter 导入 * 根 = Tk() root.g
我正在阅读本教程,它帮助我同时学习 tkinter 和 wxWidgets,但我想深入挖掘,所以想知道哪个 GUI 工具更适合深入学习,为什么? 最佳答案 不可能说哪个“更好”。两者均可用于最常见的用
看书学python,tkinter.END用在一段代码里不用解释 import tkinter def count(text, out_data): """ Update out_data w
我正在尝试使用 Python 2.7 将 Tkinter 导入到我的项目中,但我收到了错误: ImportError: No module named tkinter 在有人说之前,我已经尝试了“Tk
当我回答 Tkinter 问题时,我通常会尝试自己运行代码,但有时我会收到此错误: Traceback (most recent call last): File "C:\Python27\pyg
我是一名优秀的程序员,十分优秀!