Virtualbox Ubuntu pygame.display.set_模式在交互式python中的行为与解释文件时不同

Virtualbox Ubuntu pygame.display.set_模式在交互式python中的行为与解释文件时不同,python,ubuntu,tkinter,pygame,virtualbox,Python,Ubuntu,Tkinter,Pygame,Virtualbox,我在虚拟盒中运行Ubuntu(主机操作系统是Windows7)。我正在使用python 2.7。以下代码在各种情况下表现异常: def set_screen(): global screen screen = pygame.display.set_mode((600,600)) def set_tk(): global root global embed global tkwin root = tk.Tk() root.wm_title(

我在虚拟盒中运行Ubuntu(主机操作系统是Windows7)。我正在使用python 2.7。以下代码在各种情况下表现异常:

def set_screen():
    global screen
    screen = pygame.display.set_mode((600,600))

def set_tk():
    global root
    global embed
    global tkwin
    root = tk.Tk()
    root.wm_title("OpenBox")
    embed = tk.Frame(root, width = 600, height = 600)
    embed.pack(side=LEFT)
    windowid = embed.winfo_id()
    tkwin = tk.Frame(root, width = 200, height = 600)
    tkwin.pack(side=RIGHT)
    os.environ['SDL_WINDOWID'] = str(windowid)
    if sys.platform == "win32":
        os.environ['SDL_VIDEODRIVER'] = 'windib'
    if len(sys.argv) > 1:
        if sys.argv[1] == "-f":
            root.attributes("-fullscreen", True)

set_tk()
pygame.init()
pygame.display.init()
set_screen()
这意味着创建一个tkinter窗口,其中嵌入了pygame显示。这是我遇到的各种行为中的一些:

窗户 在windows上,代码运行良好。tkinter框架使用嵌入式pygame显示屏打开,正如预期的那样

VirtualBox Ubuntu解释文件 在Ubuntu上,当我运行程序文件(键入“python”)时,程序不工作,在调用pygame.display.set_模式时会触发此错误(如果我没有设置将pygame窗口嵌入tkinter的os环境,则不会引发此错误):

VirtualBox Ubuntu交互式python 我可以输入与键入“pythonscript.py”时不起作用的代码相同的代码,然后将其输入交互式python,代码就会起作用。交互式python和在文件上运行python之间的第一个主要区别是计时,因此我首先尝试在调用display.set_模式之前添加time.sleep(),但这没有什么区别。另一个主要区别是,它在不停止程序的情况下处理异常,所以我也尝试了尝试,除了测试之外,它没有解决问题。我也不能只在交互式python中运行整个程序(可能通过stdin和stdout上的pexpect或子进程句柄提供),因为还有tkinter线程在我的pygame显示器上维护gui侧栏,它们在交互式python中不起作用

VirtualBox Ubuntu exec 我还尝试使用exec调用display.set_模式,希望这个执行环境可能有所不同。然而,调用exec set_模式会产生与只调用set_模式相同的结果,这意味着它在交互式python中工作,但在读取文件时不工作

VirtualBox Ubuntu交互式python函数 代码在函数中的行为也不同。在交互式python中,在一个函数中运行所有这些代码将使其无法工作。当我试验函数内部哪些代码有效,哪些代码无效时,我发现必须在函数外部输入的代码是pygame.display.set_模式。奇怪的是,当我把display.set_模式单独放在一个函数中而没有其他代码时,它就工作了。当python从文件中读取代码时,上述所有情况都会引发错误


我还尝试以交互方式定义所有显示信息,然后对其进行酸洗,以便主程序加载和访问。但是,由于pygame.surface对象不能被pickle,因此这不起作用



为什么此代码在某些环境中有效,而在其他环境中无效?有没有办法让这段代码在Virtualbox Ubuntu中成功?Tkinter需要
mainloop()
才能工作。
如果没有
mainloop()
Tkinter,则立即结束工作

Windows和交互式Python可能不会为此烦恼,或者他们使用自己的mainloop来保持Tkinter运行

还有另一个问题:
mainloop()
使Tkinter工作,但它不允许运行
mainloop()
(在
mainloop()
(和Tkinter)结束工作之前)下面的任何行。因此,我使用
after()
在100毫秒后运行
set\u screen()
100毫秒-当
mainloop()
工作时

使用Python2.7.5在(非虚拟)LinuxMint16(基于Ubuntu)上测试

from Tkinter import *
import Tkinter as tk
import pygame
from pygame.locals import *
import os

def set_screen():
    global screen

    pygame.init()
    pygame.display.init()
    screen = pygame.display.set_mode((600,600))
    screen_rect = screen.get_rect()
    pygame.draw.circle(screen, (255,0,0), screen_rect.center, 50 )
    pygame.display.flip()


def set_tk():
    global root
    global embed
    global tkwin
    root = tk.Tk()
    root.wm_title("OpenBox")
    embed = tk.Frame(root, width = 600, height = 600)
    embed.pack(side=LEFT)
    windowid = embed.winfo_id()
    tkwin = tk.Frame(root, width = 200, height = 600)
    tkwin.pack(side=RIGHT)
    os.environ['SDL_WINDOWID'] = str(windowid)
    #~ if sys.platform == "win32":
        #~ os.environ['SDL_VIDEODRIVER'] = 'windib'
    #~ if len(sys.argv) > 1:
        #~ if sys.argv[1] == "-f":
            #~ root.attributes("-fullscreen", True)         
    root.after(100,set_screen)
    root.mainloop()

set_tk()

我有一个类似的设置。如果你给我提供一个最简单的工作示例,我很乐意在这里尝试一下。看起来你没有启用硬件视频加速。试试这个:我会发布更多的相关代码,虽然我不能发布整个程序,因为它很长。我也尝试过安装来宾添加。他们没有造成任何影响。我查看了virtualbox论坛,执行了他们建议的命令(“glxinfo | grep OpenGL”),但没有阻止错误。你给我的代码确实有效。但是,我实际上是在程序后面的while循环中使用root.update()。但是,我尝试在完成此操作后使用root.after调用root.update,结果成功了。我不知道为什么,但我认为使用root.after可以让tkinter长时间运行,让程序开始调用主循环。
from Tkinter import *
import Tkinter as tk
import pygame
from pygame.locals import *
import os

def set_screen():
    global screen

    pygame.init()
    pygame.display.init()
    screen = pygame.display.set_mode((600,600))
    screen_rect = screen.get_rect()
    pygame.draw.circle(screen, (255,0,0), screen_rect.center, 50 )
    pygame.display.flip()


def set_tk():
    global root
    global embed
    global tkwin
    root = tk.Tk()
    root.wm_title("OpenBox")
    embed = tk.Frame(root, width = 600, height = 600)
    embed.pack(side=LEFT)
    windowid = embed.winfo_id()
    tkwin = tk.Frame(root, width = 200, height = 600)
    tkwin.pack(side=RIGHT)
    os.environ['SDL_WINDOWID'] = str(windowid)
    #~ if sys.platform == "win32":
        #~ os.environ['SDL_VIDEODRIVER'] = 'windib'
    #~ if len(sys.argv) > 1:
        #~ if sys.argv[1] == "-f":
            #~ root.attributes("-fullscreen", True)         
    root.after(100,set_screen)
    root.mainloop()

set_tk()