Virtualbox Ubuntu pygame.display.set_模式在交互式python中的行为与解释文件时不同
我在虚拟盒中运行Ubuntu(主机操作系统是Windows7)。我正在使用python 2.7。以下代码在各种情况下表现异常: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(
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()