篇首语:本文由小编为大家整理,主要介绍了mainloop()的代码范围是多少?相关的知识,希望对你有一定的参考价值。
我想在画布上创建一个带有自定义移动小部件的python tkinter窗口来模拟运动。现在,我有一个画布,一个不动的椭圆形小部件。我在基层有问题;主循环()。我知道它会等待用户做某事,但我很难看到:
- 如何控制/查看mainloop()重复的代码(在哪里,只有tkinter?);
- 如果没有自己中断,如何正确地中断它并从另一个函数返回它;
- 应该重申什么代码?所有tkinter对象,还是仅更新更改的对象?改为使用某种更新操作?最后;
- tkinter.mainloop()和window.mainloop()之间的功能有什么区别?也许以前的问题会回答。
我对Swift有一点经验,昨天晚上开始学习非常相似的Python。我已经尝试了数百个突变到我的代码,目前正处于测试阶段。我已将所有内容移入和移出mainloop的明显范围,甚至在屏幕上都有几百个小的Python窗口。一切都做两件事之一:它什么都不做,或者给我一个错误。由于我不知道什么是运行,或者它正在运行,我无法诊断任何东西。我的目标只是重复移动一百个像素的圆圈。我已经四处寻找消息来源,但是 - 它可能是我 - 一个明显的稀缺。我的代码在这里都标记了。此页面最接近我要找的内容:Move a ball inside Tkinter Canvas Widget (simple Arkanoid game)。一切似乎都在主循环之下。那么,每一次都重绘一切?不幸的是,这是我的整个剧本;我不仅可以展示作品。它出于某种原因,只会打开一个小窗口,而不是一个全屏窗口。 (编辑:我似乎丢失了屏幕尺寸代码)
import tkinterimport time# Initial values for circle"s corners and start idicator ("b"):x1 = 10y1 = 10x2 = 210y2 = 210b = 0# Window ("window")window = tkinter.Tk()# Canvas ("area")area = tkinter.Canvas(window, width=1368, height=650)area.place(x=0, y=0)# Ovals to be placed on "area"oval1 = area.create_oval(x1,y1,x2,y2,fill="#42befe")oval2 = area.create_oval(100,10,300,210,fill="#d00000")# Turns b to 1 to start shifting when "butt" is pressed:def startFunc(): b = 1 print("b = 1")# My button to activate "startFunc" butt = tkinter.Button(window, text="Start movement", command=startFunc)butt.pack()# Adjusts the x and y coordinates when they are fed in:def Shift(A, B, C, D): print("Shift activated.") window.after(1000) print("Edit and return:") A += 100 B += 100 C += 100 D += 100 return(A, B, C, D)# Problems start about here: my Mainloop section;# I have little idea how this is supposed to be.while True: if b == 1: # Takes adjusted tuple n = Shift(x1, y1, x2, y2) print("Returned edited tuple.") # Changes coordinates x1 = n[0] y1 = n[1] x2 = n[2] y2 = n[3] print(f"{x1}, {y1}, {x2}, and {y2}") # Reiterate moving oval oval1 = area.create_oval(x1,y1,x2,y2,fill="#42befe") #Does this re-run "window" relations outside here, or only within the "while"? window.mainloop()
它应该显示一个1368乘650的窗口,而不是一个小窗口。该按钮除了打印之外什么都不做,这意味着尽管有主循环,最后的"while"仍未运行。它希望它在"while"行内循环,这应该调整坐标并移动我的蓝色圆圈。迭代可能不会触及初始值,否则会重置它们。
答案
实际上,调用mainloop与将其添加到代码中而不是调用mainloop()
相同:
while the_program_is_running(): event = wait_for_event() process_the_event(event)
根据经验,在UI初始化之后,mainloop()
应该被调用一次,并且您已准备好让用户开始与您的程序进行交互。当它退出时,你通常不会有任何代码,你的程序将退出。
如何控制/查看mainloop()重复的代码(在哪里,只有tkinter?);
我不知道“重申”是什么意思。它不会运行任何代码,除了它自己的内部代码。它只是等待事件,然后将它们分派给处理程序。
如果没有自己中断,如何正确地中断它并从另一个函数返回它;
在正在运行的程序中执行此操作非常罕见。通常,调用mainloop
是您的程序在用户开始与之交互之前执行的最后一件事,并且一旦退出程序就退出。
但是,要回答如何中断它的具体答案,可以调用根窗口的quit
方法。这将导致最近对mainloop()
的回复。
应该重申什么代码?所有tkinter对象,还是仅更新更改的对象?改为使用某种更新操作?
这个问题很难回答,因为它没有多大意义。当你调用mainloop()
时,它会监视所有tkinter对象上的所有事件。
tkinter.mainloop()和window.mainloop()之间的功能有什么区别
它们具有完全相同的效果和行为。 Tkinter奇怪地选择从任何小部件中提供mainloop
。调用它的最常用方法是来自tkinter模块本身,或来自根窗口。
我的目标只是重复移动一百个像素的圆圈。
通常的做法是创建一个将其移动一百个像素的函数。然后,该函数(或调用它的函数)可以将自己置于将来运行的事件队列中。
例如,以下代码将每秒移动一个画布对象100像素,直到程序退出:
def move_object(): the_canvas.move(item_id, 100, 0) the_canvas.after(1000, move_object)
调用它时,它会将项目向右移动100个像素。然后,它将在事件队列上对其自身进行新的调用,以便在大约1000毫秒内拾取和处理。
在本网站上有许多使用after
的工作示例,包括您在问题中链接的问题。
一切似乎都在主循环之下。那么,每一次都重绘一切?
不,不完全是。重绘的唯一对象是需要重绘的对象。在画布上移动对象,调整窗口大小,在窗口上拖动另一个窗口等,都会在事件队列上放置一个事件,告诉tkinter“此对象需要重绘”。该事件的处理由mainloop
自动发生。如果您的应用程序中没有发生任何事情,那么mainloop就不会重新绘制任何内容。
它应该显示一个1368乘650的窗口,而不是一个小窗口
那是因为你没有给主窗口一个大小。你已经给了画布一个大小,但是你使用的是place
,这不会导致包含窗口增长或缩小以适应。作为初学者,你应该完全避免使用place
而是使用pack
或grid
,因为pack
和grid
都会自动调整窗口大小以适应内部的所有内容。
虽然使用place
的感觉很简单,但实际上它通常要求你比使用其他几何管理器做更多的工作,并且它导致GUI对变化没有特别的响应。
while True:
你几乎不应该在tkinter中这样做。 Tkinter - 以及几乎所有基于事件的程序 - 都依赖于稳定的事件流。当您有一个无限循环时,它无法处理这些事件。您可以显式调用以更新循环内的屏幕,但这样做效率低,应该避免。如果你需要定期做一些事情,创建一个封装循环体的函数,然后使用after
让mainloop
在处理事件时运行它。
window.after(1000)
如果没有第二个参数,你几乎不应该以这种方式使用after
。这种用法在功能上与调用time.sleep(1)
没有区别,因为它阻止了mainloop
处理事件。您应该构造代码以允许mainloop
处理稳定的事件流。
while True: ... window.mainloop()
你肯定需要避免在循环中调用mainloop
。一个表现良好的tkinter程序应该只调用一次mainloop()
。
以上是关于mainloop()的代码范围是多少?的主要内容,如果未能解决你的问题,请参考以下文章