【发布时间】:2020-07-30 17:45:10
【问题描述】:
我是 Tkinter 编程的新手,在了解 Tkinter 如何处理类、函数等时可以使用一些帮助。
我正在尝试通过图形窗口中的按钮“分离”图形窗口。我需要能够打开类 GraphPage_cpu -> 查看带有绘图的页面,然后按“测试”按钮并让它打开一个带有 cpu 测量绘图的新窗口。
另外,我必须给用户“j_4321”一个巨大的荣誉。在弄清楚如何绘制 CPU 度量方面,他真的帮了我很多!
这是尝试分离(或在新窗口中“重新打开”图形)的主要功能:
def detach_graph(self):
self.detach_graph = Toplevel(self.parent)
self.app = GraphPage_cpu(self.detach_graph)
错误信息:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "<ipython-input-12-f73649f067eb>", line 124, in new_window
self.newWindow = Toplevel(self.parent)
AttributeError: 'GraphPage_cpu' object has no attribute 'parent'
完整代码:
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkinter import Toplevel
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showinfo, showwarning, askquestion
from tkinter import OptionMenu
from tkinter import StringVar
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
from matplotlib import style
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.dates as mdates
from psutil import cpu_percent
from psutil import virtual_memory
from datetime import datetime, timedelta
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
import sklearn.cluster as cluster
import scipy.spatial.distance as sdist
from sklearn.ensemble import IsolationForest
import pandas as pd
import numpy as np
import seaborn as sn
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
RANDOM_STATE = 42 #used to help randomly select the data points
low_memory=False
LARGE_FONT= ("Verdana", 12)
style.use("ggplot")
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
class Analyticsapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#tk.Tk.iconbitmap(self, default="iconimage_kmeans.ico") #Icon for program
tk.Tk.wm_title(self, "Advanched analytics")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, GraphPage_cpu):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text=
"Advanched analytics", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button3 = ttk.Button(self, text="CPU Usage",
command=lambda: controller.show_frame(GraphPage_cpu))
button3.pack(fill='x')
class GraphPage_cpu(tk.Frame):
def __init__(self, parent, controller, nb_points=360):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="CPU Usage", font=LARGE_FONT)
label.pack(pady=10, padx=10, side='top')
# matplotlib figure
self.figure = Figure(figsize=(5, 5), dpi=100)
self.ax = self.figure.add_subplot(111)
# format the x-axis to show the time
myFmt = mdates.DateFormatter("%H:%M:%S")
self.ax.xaxis.set_major_formatter(myFmt)
# initial x and y data
dateTimeObj = datetime.now() + timedelta(seconds=-nb_points)
self.x_data = [dateTimeObj + timedelta(seconds=i) for i in range(nb_points)]
self.y_data = [0 for i in range(nb_points)]
# create the plot
self.plot = self.ax.plot(self.x_data, self.y_data, label='CPU')[0]
self.ax.set_ylim(0, 100)
self.ax.set_xlim(self.x_data[0], self.x_data[-1])
self.canvas = FigureCanvasTkAgg(self.figure, self)
toolbar = NavigationToolbar2Tk(self.canvas, self)
toolbar.update()
button1 = ttk.Button(self, text="Back",
command=lambda: controller.show_frame(StartPage))
button1.pack(side='bottom')
button2 = ttk.Button(self, text="Test",
command=self.new_window)
button2.pack(side='bottom')
self.canvas.get_tk_widget().pack(side='top', fill=tk.BOTH, expand=True)
self.animate_cpu()
def detach_graph(self):
self.detach_graph = Toplevel(self.parent)
self.app = GraphPage_cpu(self.detach_graph)
def animate_cpu(self):
# append new data point to the x and y data
self.x_data.append(datetime.now())
self.y_data.append(cpu_percent())
# remove oldest data point
self.x_data = self.x_data[1:]
self.y_data = self.y_data[1:]
# update plot data
self.plot.set_xdata(self.x_data)
self.plot.set_ydata(self.y_data)
self.ax.set_xlim(self.x_data[0], self.x_data[-1])
self.canvas.draw_idle() # redraw plot
self.after(1000, self.animate_cpu) # repeat after 1s
app = Analyticsapp()
app.geometry('500x400')
app.mainloop()
【问题讨论】:
-
将
self.parent = parent添加到GraphPage_cpu.__init__()以便属性存在。 -
在“GraphPage_cpu.__init__()”下的“tk.Frame.__init__(self, parent)”下添加“self.parent = parent”时出现错误; “TypeError:__init__() 缺少 1 个必需的位置参数:‘控制器’”
-
在
GraphPage_cpu.__init__()方法的开头附近添加self.parent = parent不会导致该错误——不要更改tk.Frame.__init__(self, parent)调用(或其他任何内容)。
标签: python function class tkinter