Python扫雷游戏gtk3点击后获取按钮值

时间:2017-03-25 19:16:33

标签: python gtk

我用Gtk3在Python 2.7中编写简单的扫雷游戏。使用set_sensitive(False)点击后,我的标签显示值出现问题。

第一种情况我点击后使用button.hide()这样做效果很好,标签值会显示出来。

enter image description here

M - 是我的船上的

但我不想使用hide()。我希望在点击set_sensitive()属性后阻止按钮。我尝试在我的discover函数return self.button.set_sensitive(False)中执行此操作但之后我没有获得任何按钮值。我点击了所有电路板,所有按钮都被禁用。为什么我没有获得任何标签价值?

使用后登上set_sensitive(False)

enter image description here

我的代码:

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()

出了什么问题?

2 个答案:

答案 0 :(得分:1)

问题在于您在放置地雷时创建新按钮。您似乎将这些新按钮放在瓷砖的背景中。因此,如果隐藏前景中的按钮,则只能看到带有标签的按钮(即背景)。

在此修改版本中,我重复使用现有按钮,而不是这样做。如果有我的话,我只是给他们添加一个标签。我还在这些标签上使用set_no_show_all,以便在首次显示show_all网格时不显示它们。然后,发现一个图块只是显示标签是否存在,并禁用该按钮。

BTW,我还通过连接到主窗口的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()

答案 1 :(得分:0)

隐藏按钮时,还会隐藏其标签。请尝试禁用它:

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

用户将无法再次选择此字段,您将确保标签正确显示。