Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kivy Python Right Click

I'm making a game of Minesweeper with Kivy using Button widgets. I want to be able to have different actions depending on whether the mouse click is a left mouse click or a right mouse click. Can anybody help me?

Below is my Cell class and the imported modules.

Note that Cell.onPressed() is the function that is called when a button is pressed.

import kivy
from kivy.config import Config

Config.set('input', 'mouse', 'mouse,disable_multitouch')

from random import randint
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.anchorlayout import AnchorLayout

width = 10
height = 10
bombs = 5
size = 60

class Cell():  

  def __init__(self):
    self.isBomb = False
    self.isVisible = False
    self.neighbors = None
    self.location = []
    self.button = Button(size = (size, size), size_hint = (None, None))
    self.button.bind(on_press = self.onPressed)

  def build(self, x, y):
    self.location = [x, y]
    self.count_neighbors()

  def onPressed(self, instance):
    #if left_click == True:    
    self.isVisible = True
    self.button.text = str(self.neighbors)
    if self.neighbors == 0:
      for i in range(-1, 2):
        for j in range(-1, 2):
          if (0 <= self.location[0] + i < width) and (0 <= self.location[1] + j < height):
            if grid[self.location[0] + i][self.location[1] + j].isVisible == False:
              grid[self.location[0] + i][self.location[1] + j].onPressed(instance)    
    #if right_click == True:
      #Toggle state


  def count_neighbors(self):
    if self.isBomb == False:
      count = 0
      for i in range(-1, 2):
        for j in range(-1, 2):
          if (0 <= self.location[0] + i < width) and (0 <= self.location[1] + j < height):
            if grid[self.location[0] + i][self.location[1] + j].isBomb == True:
              count += 1
      self.neighbors = count

class TestApp(App):

  def build(self):
    root = AnchorLayout(anchor_x = 'center', anchor_y = 'center')
    grid_root = RelativeLayout(size = (width * size, height * size), size_hint = (None, None))
    layout = []
    for i in range(height):
      layout.append(BoxLayout(orientation='horizontal', size_hint = (.8, .8), pos = (0, (height - 1) * size - i * size)))
      for j in range(width):    
        layout[i].add_widget(grid[j][i].button)    
      grid_root.add_widget(layout[i])
    root.add_widget(grid_root)
    return root


def init_grid():
  global grid
  grid = [[Cell() for x in range(width)] for y in range(height)]
  for _ in range(bombs):
    while True:
      x = randint(0, height - 1)
      y = randint(0, width - 1)
      if grid[x][y].isBomb == False:
        grid[x][y].isBomb = True
        break  
  for i in range(width):
    for j in range(height):
      grid[j][i].build(j, i)


if __name__ == '__main__':
  init_grid()
  TestApp().run()
like image 948
Damon Palovaara Avatar asked Jun 12 '17 05:06

Damon Palovaara


2 Answers

You should bind on_touch_down instead of the on_press so you can have the touch parameter available:

...
self.button.bind(on_touch_down = self.onPressed)
...

def onPressed(self, instance, touch):
    if touch.button == 'right':
        print("right mouse clicked")
    ...
like image 94
hurturk Avatar answered Nov 11 '22 06:11

hurturk


I got something working, it's a little hackish though. I created a new class that inherits from Widget and simply changes a global variable called 'mouse'

class TouchInput(Widget):

  def on_touch_down(self, touch):
    global mouse
    mouse = touch.button

I created an instance of TouchInput() and added it to my root layout

class TestApp(App):

  def build(self):
    root = AnchorLayout(anchor_x = 'center', anchor_y = 'center')
    root_input = TouchInput()
    grid_root = RelativeLayout(size = (width * size, height * size), size_hint = (None, None))
    layout = []
    for i in range(height):
      layout.append(BoxLayout(orientation='horizontal', size_hint = (.8, .8), pos = (0, (height - 1) * size - i * size)))
      for j in range(width):    
        layout[i].add_widget(grid[j][i].button)    
      grid_root.add_widget(layout[i])
    root.add_widget(grid_root)
    root.add_widget(root_input)
    return(root)

Now anytime a button is pressed it can check whether it was a right or left click.

def onPressed(self, instance):
  if mouse == 'left':
    print('Left!')
  if mouse == 'right':
    print('Right!')
like image 23
Damon Palovaara Avatar answered Nov 11 '22 06:11

Damon Palovaara