I am making a GUI that will have two buttons. I want to perform a sort of Animation on both of those when someone hovers over them.
Now, I know that using Window.bind(mouse_pos=my_mouse_pos_func) is a workaround since no on_mouse_hover is available for button.bind() like on_press and on_release. But that isn't working for me since I cannot specify which widgets in my screen to bind my function when using Window.bind(). Doing this works in a way but only if I get the cursor in my main window.
I have searched for this a lot and in almost 90% of the results I found people recommeding Window.bind(). And the other 10% are workarounds but were really unclear to me, for e.g workarounds like "listening for mouse events" and stuff like that.
Sorry, as I am being able to provide any code as I am quite clueless as to what to show. If anyone knows any simple workarounds to this, their help will be absolutely appreciated
I use the mentioned Window.bind() in the __init__() method of my app as:
Window.bind(mouse_pos=self.on_mouse_pos)
Then in the on_mouse_pos() method, I use the collide_point() method to determine if the mouse is over any of the Buttons in question:
def on_mouse_pos(self, window, pos):
for butt in self.root.ids.butt_box.children:
if butt.collide_point(*pos):
# do something here
You just need a list of the Buttons you want to check (I use the children of a container).
I know it's an older post, but just a follow-up in case someone (like me) has the same problem and finds their way here over Google. #John Anderson's solution works, but it seems easier to me to define a class for those buttons you want to display the desired behaviour and then use Window.bind() in its __init__(), e.g.
from kivy.core.window import Window
from kivy.uix.button import Button
class MyButton(Button):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(mouse_pos=self.on_mouseover)
def on_mouseover(self, window, pos):
if self.collide_point(*pos):
# desired behaviour
That way there's no need to keep the list John mentions.
Related
I want to make Kivy mobile app that has similar swipeable Buttons (or other purpose filling widgets). In adition to that I want to have seccond type of input from same Button. For instance Gmail mobile app uses this feature:
I have this code:
main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class ItemList(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.orientation = "vertical"
self.item_list = []
for i in range(10):
self.item_list.append(Button(text=str(i),
on_release=lambda x, this_item=i: print(this_item)))
self.add_widget(self.item_list[-1])
class MainApp(App):
pass
MainApp().run()
main.kv
ItemList:
I want the program to be able to understand witch button on the list is pressed and is the press "type" a swipe or single/double/long press (any one of three will do) and excecute corresponding method.
I was looking for pre built package for this, but I maybe using the wrong keywords, since I cannot find any to suit this type of Buttons/widgets on a list aproach.
The following explanations or suggestions are based on the fact that you are new (as it seems) to Kivy.
As I understood until now, in kivy you perhaps can not expect something as ready-to-use component. But this, rather than being a downside, actually is a very effective way to let the developer choose, implement their own. There are numerous ways to program a CustomWidget, say a Button. You can change the appearance, touch feedback, texture etc. to name a few.
I want the program to be able to understand witch button on the list is pressed and is the press "type" a swipe or single/double/long press (any one of three will do) and excecute corresponding method.
To get a touch behaviour (behavior) of your own, aside from the default mixin ButtonBehavior, you can implement the required logic with three touch events on_touch_down, on_touch_move and on_touch_up. To enable a long press/ hold behaviour one way can be scheduling an action in on_touch_down event with a time threshold beyond which the action will be fired via the same event. Again to get a swipe behaviour you can implement the logic within on_touch_move event and in others' as necessary. You can also restrict the touch event to propagate further by checking collide_point, collide_widget etc.
You can track/identify any Button with its ids or by passing some argument(s) through it.
I was looking for pre built package for this, but I maybe using ...
Yes, there are some. KivyMD is one of these projects developed based on Kivy that approximates the Google's Material Design.
Exactly how do I utilize the various event methods that widgets have? Say I have a comboBox(drop down list) and I want to initiate a function every time someone changes the choice. There is the changeEvent() method in the documentation but It would be great if someone explains to me with a piece of code.
This is a pretty broad question. I recommend checking out the many tutorials on Youtube.com.
However, in your init method, put something like this:
self.ui.charge_codes_combo.currentIndexChanged.connect(self.setup_payments)
In my example, the combo box was placed on a form in Qt Designer. Self.setup_payment is a method triggered by the change in the combo box.
I hope this helps!
Is the equivalent of ToggleButton exist in PyGtk ?
I would like to have a callback like: True or False.
self.liste = gtk.ComboBox(self.liststore)
self.liste.connect("changed", self.result_list)
With this method, the program can't detect if the user clicks again on the same choice.
Thanks
I don't have any specific advice as I haven't used ComboBox much, but I'm pretty sure that what you want to do is possible.
The GTK tutorial says
ComboBox uses a TreeModel (usually a ListStore) to provide the list
items to display.
The basic ComboBox methods are great for simple things, but for more advanced usage you need to play with things at the TreeModel level yourself. To do that effectively, you need to know how they work; fortunately the docs in the tutorial are pretty good: TreeView widget, but also check out the info in the reference manual.
To make the equivalent of a toggle button you can use 14.4.8. Activatable Toggle Cells
As far as I know, only gtk.CellRendererToggle and gtk.CellRendererText can be activated. I have a gtk.CellRendererPixbuf in a gtk.TreeView which I want to make it emit a signal when clicked.
I read that the activate() function can do the job but I do not know how to implement it.
def activate(event, widget, path, background_area, cell_area, flags)
What does each of these arguments mean and how do I set/obtain them? Any examples would be extremely helpful.
Thanks in advance
I have not tried this myself before, but your question has been asked before, maybe this is of some help for you:
gtk treeview: place image buttons on rows
I have a Qt program with many buttons, user-interactable widgets, etc.
At one stage in the program, I would like all the widgets to temporarily 'stop working'; stop behaving to mouse clicks and instead pass the event on to one function.
(This is so the User can select a widget to perform meta operations. Part explanation here: Get variable name of Qt Widget (for use in Stylesheet)? )
The User would pick a widget (to do stuff with) by clicking it, and of course clicking a button must not cause the button's bound function to run.
What is the correct (most abstracted, sensible) method of doing this?
(which doesn't involve too much new code. ie; not subclassing every widget)
Is there anything in Qt designed for this?
So far, I am able to retrieve a list of all the widgets in the program (by calling
QObject.findChildren(QtGui.QWidget)
so the solution can incorporate this.
My current horrible ideas are;
Some how dealing with all the applications events all the time in one
function and not letting through the events when I need the
application to be dormant.
When I need dormancy, make a new transparent widget which recieves
mouse clicks and stretch it over the entire window. Take coordinates
of click and figure out the widget underneath.
Somehow create a new 'shell' instance of the window.
THANKS!
(Sorry for the terrible write-up; in a slight rush)
python 2.7.2
PyQt4
Windows 7
You can intercept events send to specific widgets with QObject::installEventFilter.
graphite answered this one first so give credit where credit is due.
For an actual example in PySide, here's an example you might draw some useful code from:
my_app.py
from KeyPressEater import KeyPressEater
if __name__ == "__main__":
app = QApplication(sys.argv)
eater = KeyPressEater()
app.installEventFilter(eater)
KeyPressEater.py
class KeyPressEater(QObject):
# subclassing for eventFilter
def eventFilter(self, obj, event):
if self.ignore_input:
# swallow events
pass
else:
# bubble events
return QObject.eventFilter(self,obj,event)