-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Introduce MouseButton enum for MouseEvent. #12640
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
MouseButton.LEFT/MIDDLE/RIGHT is a bit less cryptic than 1/2/3 (which remain available as MouseButton is an IntEnum). The names LEFT/MIDDLE/RIGHT are used by both Qt and wx, with the same inversion for left-handed mode as noted in the docstring. (Gtk uses PRIMARY/MIDDLE/SECONDARY, which works better for left-handed mode but seems otherwise less readable; tk just uses 1/2/3). Changed one example to demonstrate the use; I can change the other examples if we agree on the general approach. (That specific example printed mouse coordinates both on move and on click, which seems a bit redundant, so I moved the "disconnect" part to the click handler.)
Unsure if an IntEnum is better than supporting plain strings “left” etc. Pro:
Con:
|
While we do use strings everywhere, I find them typo-prone: you get an error if you write |
With „get“ you mean your IDE or a linter? Both should fail at runtime. Of course, the plain ints have to stay. Similar to the loc parameter. |
I mean at runtime.
Then it's not clear what the proposed alternative change is. |
On Linux scrolling is button 4/5, though I don't know how much that translates to the toolkits. |
Qt and GTK handle button presses completely separately from scrolls (different C-level structures / event handlers): wx handles both as MouseEvents: I think(?) Tk handles everything as strings anyways... |
Yes that's true and I agree that's a benefit. However, in this particular case I propose that it's not worth the additional verbosity and API inconsistency (in particular since we already have "up" and "down" strings).
Current solution:
Alternative proposed in this PR:
My preferred alternative:
|
I think I see the source of the confusion. You are (I believe?) thinking about the signature of the Event constructor, but that doesn't really matter -- in practice it must be exceptionally rare for end users to construct Events themselves (except for some mocking purposes, which I've done, but again that's not the main point). The main place where end users see events is the instance that's passed to them in eventhandlers ( |
I see. In that context it's ok to use an enum. Still, it's unfortunate that we currently already have an inconsistent API. |
@@ -1425,6 +1426,12 @@ def _update_enter_leave(self): | |||
LocationEvent.lastevent = self | |||
|
|||
|
|||
class MouseButton(IntEnum): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we change this to an Enum
and add
UP = 'up'
DOWN = 'down'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this will break uses like event.button == 1
.
(I guess we could override __eq__
if you really want to...).
I’m pretty sure another point in favor of using ints/ Personally, I’m not a huge fan of using a set of strings for input parameters. |
Actually I'm warming up to the idea of making MouseButton an Enum and override |
The difference in string vs int equality comparison should be absolutely negligible in this context. Just to prove:
|
I'm fine with an Not sure if an |
Well, you don't seem them in the same event handlers: buttons go to the button_press_event and scrolls to the scroll_event. |
You could of course overload |
@@ -1470,6 +1482,8 @@ def __init__(self, name, canvas, x, y, button=None, key=None, | |||
button pressed None, 1, 2, 3, 'up', 'down' | |||
""" | |||
LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent) | |||
if button in MouseButton.__members__.values(): | |||
button = MouseButton(button) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to add a check that we did not get something invalid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, there wasn't a check before, and I guess someone can always have a 25-button mouse and use MouseEvent for their own thing...
This is something I am in favor of addressing over time (and moving to more enums). |
Thoughts about just moving to Enum and override |
I think we have to use something like this. Also, when we think about moving to enums in other places that accept strings so far, this would be the way to keep backward compatibility. @tacaswell "moving to more enums". Is that intended
|
@tacaswell or @dopplershift either of you want to do the second review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes things better, and I'm not passionate about adding a validity check.
IMO, using Enum
and adding an __eq__
override just continues our poor API design in accepting too many different types for things. If anything, we should eliminate deprecate up
and down
and move them to integer values.
Ready to merge it? :) |
MouseButton.LEFT/MIDDLE/RIGHT is a bit less cryptic than 1/2/3 (which
remain available as MouseButton is an IntEnum).
The names LEFT/MIDDLE/RIGHT are used by both Qt and wx, with the same
inversion for left-handed mode as noted in the docstring. (Gtk uses
PRIMARY/MIDDLE/SECONDARY, which works better for left-handed mode but
seems otherwise less readable; tk just uses 1/2/3).
Changed one example to demonstrate the use; I can change the other
examples if we agree on the general approach. (That specific example
printed mouse coordinates both on move and on click, which seems a bit
redundant, so I moved the "disconnect" part to the click handler.)
PR Summary
PR Checklist