#python #button #kivy #grid-layout #drag
Вопрос:
Я пытаюсь создать стиль кнопки, который работает как обычная кнопка, но я также хочу иметь возможность запускать несколько кнопок одним щелчком мыши и перетаскивать по строке/столбцу кнопок, которые я пытаюсь отключить.
У меня есть некоторый стартовый код, код работает точно так, как задумано, при перетаскивании слева направо или сверху вниз, но не справа налево или снизу вверх.
Я постарался максимально упростить код. Любая помощь была бы ОЧЕНЬ признательна.
from kivy.app import App
from kivy.graphics import Color
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.core.window import Window
def pointInRect(point, rect):
x1, y1, w, h = rect
x2, y2 = x1 w, y1 h
x, y = point
if (x >= x1 and x < x2) and (y >= y1 and y < y2):
return True
return False
class TouchInput(Widget):
def __init__(self, cb, *args, **kwargs):
super(TouchInput, self).__init__(*args, **kwargs)
self.cb = cb
def on_touch_down(self, touch):
self.cb( touch.button, touch.pos )
def on_touch_up(self, touch):
self.cb( None, touch.pos )
class CustomButton(Button):
def __init__(self, name, *args, bg_color=None, **kwargs):
Window.bind(mouse_pos=self.on_mouse_pos)
super(CustomButton, self).__init__(*args, **kwargs)
self.mouse_button = None
self.mouse_entered_while_down = False
self.enabled = True
self.text = name
self.background_normal = ''
self.background_down = ''
self.default_color = (0.3, 0.1, 0.1, 1 )
self.pressed_color = (.66, .66, .66, 1)
self.disabled_color = (.125, .125, .125, 1)
toucher = TouchInput( self.on_touch )
toucher.size = self.size
toucher.pos = self.pos
self.add_widget ( toucher )
self.colorize()
def colorize(self, bg_color=None, text_color=None):
if not bg_color:
bg_color = self.disabled_color if not self.enabled else self.default_color
text_color = (1 - bg_color[0], 1 - bg_color[1], 1 - bg_color[2], bg_color[3])
self.background_color = bg_color
self.color = text_color
def on_touch(self, button, pos):
self.mouse_button = button
if pointInRect( pos, self.pos self.size ):
if self.mouse_button:
self.mouse_enter()
else:
self.mouse_leave()
def on_mouse_pos(self, *args):
pos = args[1]
if self.mouse_button:
if pointInRect( pos, self.pos self.size ):
if not self.mouse_entered_while_down:
self.mouse_enter()
else:
if self.mouse_entered_while_down:
self.mouse_leave()
def mouse_leave(self, *args):
self.enabled = not self.enabled
self.colorize()
self.mouse_entered_while_down = False
def mouse_enter(self, *args):
self.colorize(bg_color=self.pressed_color)
self.mouse_entered_while_down = True
class TestApp(App):
def build(self):
layout = GridLayout(cols=5, spacing=5, padding=5)
for i in range(25):
layout.add_widget( CustomButton(name=str(i)) )
return layout
if __name__ == '__main__':
TestApp().run()
Ответ №1:
Для всех, кто заинтересован; Я решил свою проблему со следующим кодом:
def on_touch_up(self, touch):
self.mouse_button = None
if pointInRect( touch.pos, self.pos self.size ):
self.mouse_leave()
def on_touch_down(self, touch):
self.mouse_button = touch.button
if pointInRect( touch.pos, self.pos self.size ):
self.mouse_enter()
def on_mouse_pos(self, *args):
pos = args[1]
if self.mouse_button:
if pointInRect( pos, self.pos self.size ):
if not self.mouse_entered_while_down:
self.mouse_enter()
else:
if self.mouse_entered_while_down:
self.mouse_leave()