PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.
https://www.PySimpleGUI.com
Other
13.43k stars 1.83k forks source link

[Enhancement] Check if mouse pointer is hovering element #2639

Closed elibroftw closed 4 years ago

elibroftw commented 4 years ago

Enhancement

Operating System

Windows 10

Python version

3.6.8

PySimpleGUI Port and Version

Latest

Your Experience Levels In Months or Years

3+ Python programming experience 3+ Programming experience overall Yes Have used another Python GUI Framework (tkiner, Qt, etc) previously (yes/no is fine)?

You have completed these steps:

Code or partial code causing the problem

Detecting if the scroll bar has been scrolled is pretty cool, but how would I go about checking if the mouse is hovering an element, so that the scroll event only works when the mouse is hovering the element? Example: Spotify volume slider.

PySimpleGUI commented 4 years ago

You can setup an event to get these events. Use the bind method to bind the events '<Enter>' and '<Leave>'

There's a demo program that shows you how to use bindings called Demo_Event_Binding. That demo shows binding these 2 events in fact so that you get an event when the mouse is hovered over one of the text elements.

This same technique is used to make the tooltips in the tkinter port which doesn't have tooltips as a feature.

Here's the demo code for easy access:

import PySimpleGUI as sg

"""
    Extending PySimpleGUI using the tkinter event bindings

    The idea here is to enable you to receive tkinter "Events" through the normal place you
    get your events, the window.read() call.

    Both elements and windows have a bind method.
    window.bind(tkinter_event_string, key)   or   element.bind(tkinter_event_string, key_modifier)
    First parameter is the tkinter event string.  These are things like <FocusIn> <Button-1> <Button-3> <Enter>
    Second parameter for windows is an entire key, for elements is something added onto a key.  This key or modified key is what is returned when you read the window.
    If the key modifier is text and the key is text, then the key returned from the read will be the 2 concatenated together.  Otherwise your event will be a tuple containing the key_modifier value you pass in and the key belonging to the element the event happened to.
"""
sg.theme('Dark Blue 3')

layout = [  [sg.Text('Move mouse over me', key='-TEXT-')],
            [sg.In(key='-IN-')],
            [sg.Button('Right Click Me', key='-BUTTON-'), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout, finalize=True)

window.bind('<FocusOut>', '+FOCUS OUT+')

window['-BUTTON-'].bind('<Button-3>', '+RIGHT CLICK+')
window['-TEXT-'].bind('<Enter>', '+MOUSE OVER+')
window['-TEXT-'].bind('<Leave>', '+MOUSE AWAY+')
window['-IN-'].bind('<FocusIn>', '+INPUT FOCUS+')

while True:             # Event Loop
    event, values = window.read()
    print(event, values)
    if event in (None, 'Exit'):
        break
window.close()
elibroftw commented 4 years ago

Thank you very much! Could you make it more clear in the cookbook though?

PySimpleGUI commented 4 years ago

Understand that you're not portable by using the call, but I assume that's fine since you're making something's somewhat sophisticated. The tkinter port is the easiest to extend at the moment.

The Cookbook is still being updated. There needs to be a section added specifically for extensions. I'll make sure something's said about bindings.

Like everything else in PySimpleGUI, the best place to go for examples is the folder full of demos. They should all work and they're generally commented as well. I think there's even a Trinket demo for binding events.

elibroftw commented 4 years ago

Non-portable as in OS locked or Tkinter locked? Because I'm already locked in both cases like you assumed and am using SGwx with SG.

Another request (I'll make it into a new thread if you want) For the Wx port, can you add mouse scrolling events to the system tray?

Also, you still have this 2018 empty project. Not sure what you are doing with it.

elibroftw commented 4 years ago

Also, would you like to check out my project? I told you about it 6+ months ago but I've added a shit ton of features since then. https://github.com/elibroftw/music-caster/

PySimpleGUI commented 4 years ago

Awesome... I'll check it out.

Since you're running a system tray, you may want to try the tkinter version just for fun to see what happens. In theory, in theory, you should be able to change the import for the system tray code to use the PySimpleGUI instead of Wx or Qt. The SystemTray object, methods and parameters should be identical. I'm running Wx and tkinter system trays in parallel all the time now and I'm starting to like the tkinter one more and more, perhaps because it's running on the desktop instead of in the tray which allows me to see it easier, move it, etc. I can also make the icon slightly bigger.

Here's how they look together. PySimpleGUIWx is in the try, PySimpleGUI is above it.

image

The astonishing part is that the icon is a full window. It's a window with a Graph element, or maybe it's an Image element. Don't recall but it's a full window but with no titlebar, margins, and has a transparency color set so that the alpha blend works properly.

If I'm able to get your project running, I'll try changing it over to see what happens.

Yea, I knew about the empty project. Not sure what I was doing with it at the time and simply haven't followed through.