指点成金-最美分享吧

登录

mainloop()的代码范围是多少?

佚名 举报

篇首语:本文由小编为大家整理,主要介绍了mainloop()的代码范围是多少?相关的知识,希望对你有一定的参考价值。

我想在画布上创建一个带有自定义移动小部件的python tkinter窗口来模拟运动。现在,我有一个画布,一个不动的椭圆形小部件。我在基层有问题;主循环()。我知道它会等待用户做某事,但我很难看到:

  1. 如何控制/查看mainloop()重复的代码(在哪里,只有tkinter?);
  2. 如果没有自己中断,如何正确地中断它并从另一个函数返回它;
  3. 应该重申什么代码?所有tkinter对象,还是仅更新更改的对象?改为使用某种更新操作?最后;
  4. 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而是使用packgrid,因为packgrid都会自动调整窗口大小以适应内部的所有内容。

虽然使用place的感觉很简单,但实际上它通常要求你比使用其他几何管理器做更多的工作,并且它导致GUI对变化没有特别的响应。

while True:

你几乎不应该在tkinter中这样做。 Tkinter - 以及几乎所有基于事件的程序 - 都依赖于稳定的事件流。当您有一个无限循环时,它无法处理这些事件。您可以显式调用以更新循环内的屏幕,但这样做效率低,应该避免。如果你需要定期做一些事情,创建一个封装循环体的函数,然后使用aftermainloop在处理事件时运行它。

window.after(1000)

如果没有第二个参数,你几乎不应该以这种方式使用after。这种用法在功能上与调用time.sleep(1)没有区别,因为它阻止了mainloop处理事件。您应该构造代码以允许mainloop处理稳定的事件流。

while True: ... window.mainloop()

你肯定需要避免在循环中调用mainloop。一个表现良好的tkinter程序应该只调用一次mainloop()

以上是关于mainloop()的代码范围是多少?的主要内容,如果未能解决你的问题,请参考以下文章