我尝试了pygame和tkinter,但都用while循环阻塞了主线程。有一些变通办法,但我认为它们相对来说比较复杂。例如,在Java中,我可以创建一个JFrame,添加一个JPanel并在JPanel上绘制。这不会阻塞JFrame/JPanel在其上创建的线程。Python和Java之间是否有一个关键的区别,使得Python不能做同样的事情,或者我只是使用了错误的包,还是使用了错误的包?在
编辑1: 主要问题:在Python中打开一个窗口并在其上绘制一个填充矩形而不阻塞主线程的最简单方法。在
编辑2:
tkinter示例:
import tkinter
root = tkinter.Tk()
canvas = tkinter.Canvas(root)
canvas.create_rectangle(10, 10, 60, 60, fill='blue')
canvas.pack()
tkinter.mainloop()
print("I won't get printed until window is closed")
pygame示例:
^{pr2}$我想要的:
class Canvas:
def __init__(self):
... # create window that does not block main thread
def draw_rect(self, x, y, width, height, color):
... # draw rect on window
def clear(self):
... # clear window
canvas = Canvas()
canvas.draw_rect(10, 10, 60, 60, 'blue')
print('I get printed even while window is active')
编辑3:
我想要Java语言:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class Canvas {
public static void main(String[] args) {
// test the Canvas class
Canvas canvas = new Canvas(500, 500); // creates canvas window
canvas.fillRect(50, 50, 200, 200, Color.BLUE); // draws a rect
canvas.clear(); // removes all drawings from canvas window
canvas.fillRect(50, 100, 300, 200, Color.RED);
canvas.fillRect(100,150,300,300, Color.CYAN);
// everything here will be executed
}
private JFrame frame = new JFrame();
private List<Consumer<Graphics>> drawTasks = new ArrayList<>();
public Canvas(int width, int height) {
JPanel panel = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
for (Consumer<Graphics> drawTask : drawTasks) {
drawTask.accept(g);
}
}
};
panel.setPreferredSize(new Dimension(width, height));
frame.add(panel);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void fillRect(int x, int y, int width, int height, Color color){
drawTasks.add(graphics -> {
graphics.setColor(color);
graphics.fillRect(x, y, width, height);
});
frame.repaint();
}
public void clear() {
drawTasks.clear();
frame.repaint();
}
}
运行Java代码时,会创建一个单独的线程(事件调度线程),为您处理GUI。pygame中的等效项如下所示:
但是,正如您自己看到的,如果您运行这段代码,它将无法工作,因为pygame的事件系统只有在从主线程调用时才能正常工作(至少在Windows上)。它在linuxirc中工作)。在
所以你所要求的在pygame中是不可靠的。在
使用tkinter,您可以使用以下内容:
^{pr2}$这可以工作,但有点不太好,因为
tkinter
模块必须导入到调用mainloop()
的同一线程中。在相关问题 更多 >
编程相关推荐