tkinter,你怎么能拖过按钮?

时间:2017-10-21 15:51:50

标签: python python-3.x tkinter

所以我有一个简单的程序,当你从网格中点击一个按钮时,它将填充一种颜色。我希望能够在按钮上拖动并填充它们,这与您必须单击每个按钮的那一刻不同。可以这样做吗?

这是我的代码可能不是最好的:

LatLng myCoordinates = new LatLng(location.getLatitude(), location.getLongitude());
        player.setPosition(myCoordinates);
        CameraPosition currentPosition = map.getCameraPosition();
        CameraPosition cameraPosition = new CameraPosition.Builder()
                .target(myCoordinates)
                .bearing(currentPosition.bearing)
                .zoom(18)
                .tilt(currentPosition.tilt)
                .build();
        map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

1 个答案:

答案 0 :(得分:2)

以这种方式:

from tkinter import *

root=Tk()

grid= Frame(root)
grid.pack()

img0=PhotoImage(file="0.png")
img1=PhotoImage(file="1.png")
img2=PhotoImage(file="2.png")

fill = 1

class button:

    def __init__(self, x, y):

        self.type=0

        self.but=Button(grid,command=self.change, image=img0, borderwidth=0)
        self.but.grid(row=y, column=x)

        #Changed
        self.already_changed = False

    def change(self):
        if self.type==fill:
            self.but.config(image=img0)
            self.type=0
        else:
            self.but.config(image=eval("img"+str(fill))) #I left this in here, but you should NEVER use eval(). It's unsafe.
            self.type=fill

    #Changed
    def mouse_entered(self):
        if not self.already_changed:
            self.change()
            self.already_changed = True

    def mouse_up(self):
        self.already_changed = False

#Changed
class Container:
    def __init__(self, x, y):
        grid_buttons = []

        for Y in range(y):
            grid_buttons.append([])
            for X in range(x):
                grid_buttons[Y].append(button(X, Y))

        self.buttons = grid_buttons
        grid.bind_all("<Button-1>", self.mouse_down)
        grid.bind_all("<ButtonRelease-1>", self.mouse_up)
        grid.bind_all("<B1-Motion>", self.mouse_motion)
        self.mouse_pressed = False

    def mouse_down(self, e):
        self.mouse_pressed = True

    def mouse_up(self, e):
        self.mouse_pressed = False
        for row in self.buttons:
            for but in row:
                but.mouse_up()

    def mouse_motion(self, e):
        for row in self.buttons:
            for but in row:
                if grid.winfo_containing(e.x_root, e.y_root) is but.but:
                    but.mouse_entered()

container = Container(15,15)

root.mainloop()

现在,我注意到你所做的一些事情并不是Python风格。所以这是一个更接近Python惯例的版本。请注意,这是完全不同的。

from tkinter import *

root = Tk()

images = {0: PhotoImage(file="0.png"),
          1: PhotoImage(file="1.png"),
          2: PhotoImage(file="2.png")}

fill = 1

class MyButton(Button): #Convention is for class names to start with uppercase letters
    def __init__(self, master):
        super(MyButton, self).__init__(master, image = images[0], borderwidth = 0)
        self.type = 0
        self.already_changed = False

    def change(self):
        if self.type == fill:
            self.type = 0
        else:
            self.type = fill
        self.config(image=images[self.type])

    def mouse_entered(self):
        if not self.already_changed:
            self.change()
            self.already_changed = True

    def mouse_up(self):
        self.already_changed = False

class Container(Frame):
    def __init__(self, master, width, height):
        super(Container, self).__init__(master)

        buttons = []

        for y in range(height):
            buttons.append([])
            for x in range(width):
                button = MyButton(self)
                button.grid(row = x, column = y)

                buttons[y].append(button)

        self.buttons = buttons

        self.bind_all("<Button-1>", self.mouse_down)
        self.bind_all("<ButtonRelease-1>", self.mouse_up)
        self.bind_all("<B1-Motion>", self.mouse_motion)

        self.mouse_pressed = False

    def mouse_down(self, e):
        self.update_containing_button(e)
        self.mouse_pressed = True

    def mouse_up(self, e):
        self.mouse_pressed = False
        for row in self.buttons:
            for button in row:
                button.mouse_up()

    def mouse_motion(self, e):
        self.update_containing_button(e)

    def update_containing_button(self, e):
        for row in self.buttons:
            for button in row:
                if self.winfo_containing(e.x_root, e.y_root) is button:
                    button.mouse_entered()

grid = Container(root, 15, 15)
grid.pack()

root.mainloop()

为什么要发布?因为看起来您在实际应用程序中有更多代码(这很好,它只是一个最小的例子)。我并不想强迫您重写我的代码以使其与其余代码一起使用,反之亦然。

两个版本之间的功能差异:

  • 第二个版本已被修改,因此它使用面向对象的功能而不是全局变量,使其更灵活,更容易更改。

  • 第二个版本删除了按钮本身的绑定,而不是让容器处理所有内容。