简体   繁体   English

单击后,Python minesweeper游戏gtk3获取按钮值

[英]Python minesweeper game gtk3 get button value after click

I write simple minesweeper game in Python 2.7 with Gtk3. 我使用Gtk3在Python 2.7中编写了简单的扫雷游戏。 I have a problem with show value of label after click using set_sensitive(False) . 使用set_sensitive(False)单击后,标签显示值出现问题。

First case I use button.hide() after click and this works good, label value are shows up. 第一种情况是单击后使用button.hide() ,效果很好,显示了标签值。

在此处输入图片说明

M - is a mine on board M-是船上的地雷

But I don't want to use hide() . 但是我不想使用hide() I want to block button after click with set_sensitive() property. 我想使用set_sensitive()属性单击后阻止按钮。 I try do this in my discover function return self.button.set_sensitive(False) but after that I don't get any value of my buttons. 我尝试在我的discover函数return self.button.set_sensitive(False)执行此操作,但是此后我没有任何按钮值。 I clicked all board and all buttons are disable. 我单击了所有面板,所有按钮均被禁用。 Why I don't get any value of label? 为什么我没有任何标签价值?

Board after use set_sensitive(False) 使用后板set_sensitive(False)

在此处输入图片说明

My code: 我的代码:

import gi
from random import randrange

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk


class SaperButton(Gtk.Button):
    def __init__(self):
        Gtk.Button.__init__(self)
        self.set_size_request(50, 50)


class Cell:
    def __init__(self):
        self.mine = False
        self.neighbormines = 0
        self.button = SaperButton()

    def place_mine(self):
        self.mine = True

    def is_mine(self):
        return self.mine

    def discover(self):
        print 'discover'
        # with hide showing values of label
        # with return self.button.set_sensitive(False) don't show
        return self.button.hide()

    def is_discovered(self):
        return not self.button.get_visible()

    def set_nighbromines(self, number):
        self.neighbormines = number

    def get_nighbromines(self):
        return self.neighbormines

    def get_button(self):
        return self.button


class SaperGrid(Gtk.Grid):
    def __init__(self, rows, cols, ratio):
        self.rows = rows
        self.cols = cols
        self.cells = []
        self.ratio = ratio
        Gtk.Grid.__init__(self)

        for row in range(rows):
            for col in range(cols):
                cell = Cell()
                self.cells.append(cell)
                self.attach(cell.get_button(), row, col, 1, 1)

        self.place_mines()

    def get_cells(self):
        return self.cells

    def get_row_col_button(self, index):

        return (index / self.cols, index % self.cols)

    def place_mines(self):
        mines = 0
        while mines < (self.rows * self.cols * self.ratio):

            row = randrange(0, self.rows)
            col = randrange(0, self.cols)

            i = self.get_index(row, col)

            if not self.cells[i].is_mine():

                mines += 1
                self.cells[i].place_mine()

                button = Gtk.Button()
                label = Gtk.Label("M")
                button.add(label)

                self.attach(button, row, col, 1, 1)

        for i, val in enumerate(self.cells):
            print self.cells[i]

    def get_index(self, row, col):
        return (row * self.cols) + col

    def discover_cell(self, row, col):
        index = self.get_index(row, col)
        print 'index', index
        self.cells[index].discover()

    def discover_all_cells(self):
        for cell in self.cells:
            cell.discover()


class Saper:
    def __init__(self, rows, cols):
        self.window = Gtk.Window()
        self.rows = rows
        self.cols = cols
        self.vbox = Gtk.VBox()
        self.window.add(self.vbox)
        self.create_grid(rows, cols)

    def create_grid(self, rows, cols):

        self.grid = SaperGrid(rows, cols, 0.10)

        for i, cell in enumerate(self.grid.get_cells()):
            (row, col) = self.grid.get_row_col_button(i)
            print 'Button connect in col {} row {}'.format(col, row)
            cell.get_button().connect('clicked', self.clicked_handler, row, col)

        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.vbox.pack_start(self.grid, expand=True, fill=True, padding=0)

    def clicked_handler(self, button, row, col):
        cell_index = self.grid.get_index(row, col)

        self.grid.discover_cell(row, col)

    @staticmethod
    def exit(self, widget, data=None):
        Gtk.main_quit()


win = Saper(5, 5)
win.window.show_all()
Gtk.main()

What's is wrong? 怎么了

The problem is that you create new buttons when placing your mines. 问题是您在放置地雷时创建了新按钮。 It seems you put those new buttons in the background of your tiles. 似乎您将这些新按钮放在了瓷砖的背景中。 Thus, you can only seen the button with the label (which is the background) if you hide the button that is in the foreground. 因此,如果您隐藏位于前台的按钮,则只能看到带有标签(即背景)的按钮。

Instead of doing this, in this modified version I reuse the existing buttons. 而不是这样做,在此修改版本中,我重用了现有按钮。 I just add a label to them if there is a mine. 如果有地雷,我只是给他们加标签。 I also use the set_no_show_all on those labels, so that they are not shown when the grid is first display with show_all . 我也用set_no_show_all这些标签,这样,当电网与第一显示他们没有显示show_all Then, discovering a tile is just a matter of showing the label if it exists, and disabling the button. 然后,发现图块仅是显示标签(如果存在)并禁用按钮的问题。

BTW, I also fixed exiting the application by connecting to the destroy signal of the main window and calling gtk_main_quit . 顺便说一句,我还通过连接到主窗口的destroy信号并调用gtk_main_quit来固定退出应用程序。

import gi
from random import randrange

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk


class SaperButton(Gtk.Button):
    def __init__(self):
        Gtk.Button.__init__(self)
        self.set_size_request(50, 50)


class Cell:
    def __init__(self):
        self.mine = False
        self.neighbormines = 0
        self.button = SaperButton()

    def place_mine(self):
        self.mine = True
        label = Gtk.Label("M")
        label.set_no_show_all(True)
        self.button.add(label)

    def is_mine(self):
        return self.mine

    def discover(self):
        print 'discover'
        label = self.button.get_child()
        if label is not None:
            label.show()
        self.button.set_sensitive(False)

    def is_discovered(self):
        return not self.button.get_visible()

    def set_nighbromines(self, number):
        self.neighbormines = number

    def get_nighbromines(self):
        return self.neighbormines

    def get_button(self):
        return self.button


class SaperGrid(Gtk.Grid):
    def __init__(self, rows, cols, ratio):
        self.rows = rows
        self.cols = cols
        self.cells = []
        self.ratio = ratio
        Gtk.Grid.__init__(self)

        for row in range(rows):
            for col in range(cols):
                cell = Cell()
                self.cells.append(cell)
                self.attach(cell.get_button(), row, col, 1, 1)

        self.place_mines()

    def get_cells(self):
        return self.cells

    def get_row_col_button(self, index):

        return (index / self.cols, index % self.cols)

    def place_mines(self):
        mines = 0
        while mines < (self.rows * self.cols * self.ratio):

            row = randrange(0, self.rows)
            col = randrange(0, self.cols)

            i = self.get_index(row, col)

            if not self.cells[i].is_mine():
                mines += 1
                self.cells[i].place_mine()

        for i, val in enumerate(self.cells):
            print self.cells[i]

    def get_index(self, row, col):
        return (row * self.cols) + col

    def discover_cell(self, row, col):
        index = self.get_index(row, col)
        print 'index', index
        self.cells[index].discover()

    def discover_all_cells(self):
        for cell in self.cells:
            cell.discover()


class Saper:
    def __init__(self, rows, cols):
        self.window = Gtk.Window()
        self.rows = rows
        self.cols = cols
        self.vbox = Gtk.VBox()
        self.window.add(self.vbox)
        self.create_grid(rows, cols)
        self.window.connect('destroy', Gtk.main_quit)

    def create_grid(self, rows, cols):

        self.grid = SaperGrid(rows, cols, 0.10)

        for i, cell in enumerate(self.grid.get_cells()):
            (row, col) = self.grid.get_row_col_button(i)
            print 'Button connect in col {} row {}'.format(col, row)
            cell.get_button().connect('clicked', self.clicked_handler, row, col)

        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.vbox.pack_start(self.grid, expand=True, fill=True, padding=0)

    def clicked_handler(self, button, row, col):
        cell_index = self.grid.get_index(row, col)
        self.grid.discover_cell(row, col)



win = Saper(5, 5)
win.window.show_all()
Gtk.main()

When you hide the button, you also hide its label. 隐藏该按钮时,还隐藏其标签。 Try to disable it instead: 尝试禁用它:

button.set_state_flags(Gtk.StateFlags.INSENSITIVE, True)

User won't be able to select this field again and you'll be sure that the label is displayed correctly. 用户将无法再次选择此字段,并且您将确保标签显示正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM