社区首页 >问答首页 >为什么图形窗口在大约5秒后就会冻结?

为什么图形窗口在大约5秒后就会冻结?
EN

Stack Overflow用户
提问于 2019-08-29 15:15:36
回答 1查看 139关注 0票数 4

代码运行正常,如我所料,但5秒后,图形显示将永久冻结。它没有错误,没有,只是停止了响应。

这是一个用来模拟一大群物体运动的程序。在无目标的情况下,就像布朗运动一样,它们必须随意移动。为了做到这一点,我使用Pygame绘制任意对象作为任意位置的矩形,为了移动它们,我删除了所有的东西,然后再绘制它们,它们的位置被随机更改为1。我正在使用吡咯来显示图形。你能不能为这个问题提出一个更好的解决方案?

代码语言:javascript
代码运行次数:0
复制
import pygame, random, sys, time, numpy
from pygame.locals import *

black = (0,0,0)
white = (255,255,255)

clock = pygame.time.Clock()

class people():

    def __init__(self):

        screen = pygame.display.get_surface()

        self.x = random.randint(0, 800)
        self.y = random.randint(0, 600)

    def move(self):
        self.x += random.randint(-1, 1)
        self.y += random.randint(-1, 1)
        if self.x < 0:
            self.x = 0
        if self.x > 800:
            self.x = 800
        if self.y < 0:
            self.y = 0
        if self.y > 600:
            self.y = 600

    def place(x, y):
        screen = pygame.display.get_surface()
        pygame.draw.rect(screen, black, [x, y, 10, 10])

def main():
    # Initialise screen
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption('Test')

    peoples = []

    chosepopul = 1

    while chosepopul == 1:
        try:
            population = abs(int(input("How many people would you like to have")))
            chosepopul = 0
        except:
            print("Number, please")    

    for i in range(population):
        peoples.append(people())

    while True:

        screen.fill(white)

        for obj in peoples:

            people.place(obj.x, obj.y)

            people.move(obj)

        pygame.display.update()
        clock.tick(60)

if __name__ == '__main__':
    main()

pygame.quit()
quit()

一切都如我所料,但不可避免地会结冰。

更新:如果我将输入脚本更改为常量,则一切都正常工作。因此,这个问题在某种程度上与用户界面交互有关。

EN

回答 1

Stack Overflow用户

发布于 2019-08-29 16:00:30

程序停止,因为input()阻止了程序流。不再发送和处理进一步的PyGame更新或事件。基本上,一切都会停止,等待用户输入。

解决这个问题的最好方法是编写代码,这样用户就可以在屏幕上输入一些PyGame,而不是在控制台中。也许做一个滑块或旋转控件来选择数字,或者加/减按钮,什么的。

或者,程序仍然可以在使用post()函数将结果发送到主PyGame事件循环线程的线程中使用控制台输入。

我必须承认,这个答案只是学术上的兴趣,因为使用控制台与PyGame窗口一起输入是非常丑陋的!

总之,这是一些代码。主python窗口只需每0.5秒更改一次颜色,而用户可以使用标准python input()函数在控制台中输入文本。代码使用它自己的事件枚举类型来发布消息,但这些也可能只是普通的数字。

按照OP,这是可行的,因为input()函数是在执行的子线程中调用的。这样,主线程就可以继续处理PyGame事件队列,并对窗口进行更新。只有一个事件队列/循环(原因超出了这个答案的范围)是很重要的,因此子线程将事件“发布”回主线程,而不是对窗口/事件本身采取行动。

代码语言:javascript
代码运行次数:0
复制
import threading
import pygame
import enum

# Window size
WINDOW_WIDTH  = 200
WINDOW_HEIGHT = 200

DARK    = (  50, 50, 50 )
WHITE   = ( 255,255,255 )
RED     = ( 255, 55, 55 )
GREEN   = (   5,255, 55 )
BLUE    = (   5, 55,255 )


colour_cycle = [ DARK, WHITE, RED, GREEN, BLUE ]


class UserEvents( enum.IntEnum ):
    CLIENT_NUMBER = pygame.USEREVENT + 1
    CLIENT_QUIT   = pygame.USEREVENT + 2
    # ...



class ConsoleInputThread( threading.Thread ):
    """ A thread that handles user input on the console.
        Waits for user input, then posts messages
        to the main PyGame thread for processing """
    def __init__( self, prompt ):
        threading.Thread.__init__(self)
        self.daemon         = True # exit with parent
        self.done           = False
        self.prompt         = prompt

    def stop( self ):
        self.done = True

    def run( self ):
        """ Loops until the user hangs-up """
        while ( not self.done ):
            # Get some input from the user
            user_input = input( self.prompt ).strip()
            new_event = None
            if ( user_input == 'quit' ):
                new_event = pygame.event.Event( UserEvents.CLIENT_QUIT, { } )
            else:
                try:
                    user_input = int( user_input )
                    new_event = pygame.event.Event( UserEvents.CLIENT_NUMBER, { "value":user_input } )
                except:
                    print( "Syntax Error" )
            # If we received valid input post it to the main thread
            if ( new_event ):
                pygame.event.post( new_event )




###
### MAIN
###

# Create the window
pygame.init()
pygame.display.set_caption("Socket Messages")
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW  = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )


# Start the console-input thread
input_thread = ConsoleInputThread( "How many people would you like to have: " )
input_thread.start()

# Main paint / update / event loop
done = False
clock = pygame.time.Clock()
colour_index = 0
while ( not done ):

    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True

        elif ( event.type == UserEvents.CLIENT_QUIT ):
            print("\nCLIENT ASKED TO QUIT " )
            done = True

        elif ( event.type == UserEvents.CLIENT_NUMBER ):
            print( "\nVALUE WAS INPUT: %d " % ( event.value, ) )


    WINDOW.fill( colour_cycle[colour_index] )
    # rotate the colours, just so the screen changes
    colour_index += 1
    if ( colour_index >= len( colour_cycle ) ):
        colour_index = 0

    pygame.display.flip()

    clock.tick_busy_loop(2)  # NOTE: 2 frames per second, no flashy-flashy

input_thread.stop()
pygame.quit()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57718723

复制
相关文章
this 指向4 — 事件处理函数中的 this
本文继续讨论 this 指向 问题,今天讨论: 事件处理函数中的 this 文末尾有关于this的面试题,可直接查看 0 1 事件处理函数中的 this 示例1: <button id="btnTest" onclick="console.log(this)">Test</button> <button id="btnTest2" onclick="(function(){console.log(this)})()"> Test2</button> 点击结果为: 示例2: //场景1 let
用户9914333
2022/07/22
8460
this 指向4  — 事件处理函数中的 this
js 中的构造函数,构造函数作用,构造函数和普通函数的区别
函数的定义方式: 1.声明式函数定义: function 函数名 (){};这种定义方式,会将函数声明提升到该函数所在作用域的最开头,也是就无论你在这个函数的最小作用域的那儿使用这种方式声明的函数,在这个作用域内,你都可以调用这个函数为你所用。 2.函数表达式:let fun = function(){}; 此方式定义的函数,只能在该作用域中,这段赋值代码执行之后才能通过fun()调用函数,否则,由于变量声明提升,fun === undefined。 3.new Function 形式: var fun1 = new Function (arg1 , arg2 ,arg3 ,…, argN , body );Function构造函数所有的参数都是字符串类型。除了最后一个参数, 其余的参数都作为生成函数的参数即形参。这里可以没有参数。最后一个参数, 表示的是要创建函数的函数体。
全栈程序员站长
2022/10/04
3.5K0
Python中的构造函数
Python中的构造函数是__init__函数。在Python中,子类如果定义了构造函数,而没有调用父类的,那么Python不会自动调用,也就是说父类的构造函数不会执行。
用户7886150
2020/12/20
1.7K0
java构造函数调用另一个构造函数_java中的构造函数
* 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法
用户7886150
2021/04/29
4.5K0
Dom 事件处理函数
别人整理的,我顺手就给捏来了哈哈。很详细的一些事件,浏览器支持情况,以及详细的说明。在这里向整理者致敬。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr
练小习
2017/12/29
8480
虚函数中构造函数的调用顺序
1 /*曾经有段时间一直被构造函数中的虚函数所困扰,现在通过自己重新学习了一遍,标注一下容易忘记的知识*/ 2 #include<iostream> 3 using namespace std; 4 class Base0 5 { 6 public: 7 Base0(int var):var0(var) 8 { 9 cout<<"Construct base0"<<endl; 10 } ; 11 int var0; 12 void fun()
Gxjun
2018/03/22
3.5K0
虚函数中构造函数的调用顺序
【Kotlin】类的初始化 ② ( 主构造函数 | 主构造函数定义临时变量 | 主构造函数中定义成员属性 | 次构造函数 | 构造函数默认参数 )
在 Kotlin 类中 , 可以在 类声明 时 在 类名后 定义 " 主构造函数 " ;
韩曙亮
2023/03/30
4.9K0
继承中的构造方法内存处理
实际上在面向对象第一天的讲解当中,我们对内存方面做了一些隐瞒。因为除了Object类,所有的类都是有父类的。但是我们在考虑内存图时忽略了这点,现在,我们来简单描述加入了子父类关系后的对象内存图。
星哥玩云
2022/09/14
4810
继承中的构造方法内存处理
【学习笔记】SWIFT中的构造函数
2017-05-05 by Liuqingwen | Tags: Swift | Hits
IT自学不成才
2019/01/08
1.2K0
React的事件处理函数用法详解!
页面交互必然会伴随事件的发生,譬如HTML中的一个button被点击了一下,接下来页面应该怎么反应?就是需要button的onClick事件函数来处理。
Learn-anything.cn
2021/11/28
9000
C++构造函数 | 构造函数
C++在建立一个对象时,常常需要作某些初始化,如果一个数据成员未被赋值,则它的值是不可预知的,因为在系统为它分配内存时,保留了这些存储单元的原状,这就成为了这些数据成员的初始值,在C++中,对象是一个实体,它反映了客观事物的属性,是应该有确定的值的。
小林C语言
2021/01/26
2.2K0
C++构造函数 | 构造函数
react中的事件处理(二)
在React中,事件处理函数通常会与组件的状态(state)进行交互。我们可以通过更新状态来响应事件的发生。
堕落飞鸟
2023/05/19
8200
react中的事件处理(一)
React中的事件绑定采用了类似于HTML中的方式,但有一些语法上的差异。我们可以在组件中定义事件处理函数,并将其绑定到特定的事件上。
堕落飞鸟
2023/05/19
7080
解析C#类中的构造函数
彭泽0902
2018/01/04
3.4K0
关于C#事件处理函数中的参数(object sender, EventArgs e)
1、是事件源,表示触发事件的那个组件 如(button/label/listview...),比如说你单击button,那么sender就是button
zls365
2021/02/26
2.2K0
C++中类的构造函数和析构函数
构造函数 对象创建的时候执行 student s //空参构造函数 栈内存中 student s("测试")//带参构造函数 栈内存中 或者 student *s=new student//空参构造函
乱码三千
2021/07/29
2K0
C++中类的构造函数和析构函数
Java里的构造函数(构造方法)
本文转载之https://www.cnblogs.com/livterjava/p/4709561.html
用户7886150
2021/01/31
2.5K0
创造特殊的构造函数——寄生构造函数模式
当我们需要构造一个特殊的数据,我们可以通过寄生构造函数来实现。比如我们要格式化一个Array(简单举例),将其变成一个有“|”组成的字符串,我们可以这么做:
就只是小茗
2018/12/07
9530
点击加载更多

相似问题

函数可以处理'keypress‘事件,但不能处理我激发的相同的'keypress’事件

27

构造函数内部的事件处理

12

构造函数中的事件处理程序与事件处理程序在构造函数之外的行为不同。

11

未激发隐藏事件处理程序

10

UserControl的事件处理程序不会激发

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文