How do I make a function triggered by pressing right click? - python

I'm working on a game involving turtle for a school project and I want to end it when the player right clicks on anything but I've been researching for ages and I can't find how to key bind a right click and every module i import but turtle won't work.
I tried importing pyautogui, pydirectimput, tkinter and many more to try and find work arounds becuase it has to be a right click but the imports wont work. I've tried treating it like a normal key bind but that won't work; maybe I'm not using capitals and underscores correctly, I don't know how to do it and it's due in 7 hours. Please help.

I don't know turtle much, but I think this should work:
def bar():
# do stuff here
# Test this with either a 2 or a 3, idk which one it is
turtle.onscreenclick(bar, 2, True)
It will bind the right click event to this bar function.
Tell me if it does not work!
Edit: I had used the wrong method sorry!
It's actually "onscreenclick".

Related

Does Python evdev library have an event specific grab or passthrough?

A python evdev device has a .grab() function that prevents other processes from getting input events on the device. Is there any way to limit this to specific events from a device?
For my example, if I .grab() a pen input device that has pressure sensitivity and tilt and 2 click buttons on the side, how would I 'grab' ONLY the 2 click buttons but let the rest of the input (the tip, pressure sensitivity and tilt) be caught by the rest of the system as normal?
One of my pen buttons is normally a right click mouse event. I want to make it do something else but it still pops up the right click menu so I'm trying to figure out how to stop that.
I tried doing the grab and ungrab when the event occurs. Like event > grab > do my stuff > ungrab. But that is obviously too late and the OS still pops up the menu.
I tried doing the full grab, then in the event loop if it is a button press do my stuff, otherwise create a UInput event injection by just passing the event back to the system. This was a bit of a tangled mess. Permissions are required. When I finally got past that, the movement was offset and the pressure/tilt wasn't working... I think it is something to do with the DigiMend driver that actually makes that stuff work and/or xinput settings I have to pass to calibrate the tablet. But I'm not interested in writing all the pressure/tilt functionality from scratch or anything like that, so I need the DigiMend stuff to work as normal. So I gave up on this idea for now.
The only other thought I had was figure out why the OS defaults to the behavior it does and see if I can just manually disable the actions (i.e. Why does it think that button is a right mouse click and make it think that button is nothing instead.)
So I guess this is a 3 level question.
Can I achieve the the grab functionality on select events instead of the device as a whole?
If the passthrough idea was better, is there a way to achieve this without having to do any permission modifications and be able to pass the exact event (i.e. no offset and such that I experienced?)
If evdev does not have this ability or it'd be easier to do in another way, like disabling the defaults for the pen in the OS somehow, I am open to suggestions. I am using Kubuntu 20.04 if that helps.
Any help would be appreciated, let me know if more info is needed, thanks in advance!
I ended up going with #3 and using xinput. Figured I'd put up this answer for now in case others come across this and want to do something similar.
The workaround was actually kind of simple. I just use xinput to remap the 2 buttons. So evdev doesn't have to grab at all. Just disable those buttons and everything goes normally except those, which I listen for with evdev.
xinput set-button-map {} 1 0 0 4 5 6 7
My device has 7 buttons and are normally mapped 1-7. Which are all mouse equivalents of left click, middle click, right click, etc...
By using that string and passing the device ID in for the {} I just run that with subprocess first. And voila, no more right click menu. And I can use evdev to map the events to whatever I want.

Pygame window wont move or close after using tkinter

I have had this problem for ages now with many different projects now, so I really want to find out how to fix it. For example, in one of my projects, I created a level editor for a game. The level editor had the option to save and load different levels from a file using tkinter.filedialog.
Now after I select the file, the game will still work, but the 'X' close button doesn't work anymore, and I can't move the window.
The game itself works as usual, and I can still interact with everything inside of the window, but I can't move or close the window.
Thanks in advance.
Ok. I figured this one out. The problem went away when I called the tkinter functions from a key press, not a mouse press.

How to detect mouse scroll and mouse position in Python and then make some actions with it?

I would like to make a program for displaying some information and help (like it is sometimes done at libraries or in other public places). So basically some information screen. The problem is I would like to prevent the user from exiting the program and scrolling up, to see what others typed.
I would like to do that without importing big libraries like Pygame. There are plenty of modules for automatic mouse movement and and mouse clicks, but almost no modules for detecting it. If you know some please write them here. I am using Windows 10 and 7.
Try pynput. It's a bit fiddly to use when capturing, but can capture keyboard and mouse and also emit both.
This answer doesn't really answer the question asked in the title:
However it might answer the use case that you describe:
I don't have a windows computer at hand for testing:
but perhaps this could work:
import os
os.system('cls')
# now rewrite the lines, that a user is allowed to see.
Theoretically cls is supposed to clean the windows screen buffer and you wouldn't see any history and it should be impossible to scroll back.
I think most other solutions would quickly become complicated or could be circumvented by a user with some combinations of key presses and mouse movements.
However you had to explicitely rewrite whatever you want to keep on the display.

Watching the flow of execution by “single-stepping” in PyScripter

Ok, in fact, I did found a way how to single step into the code, but I still can't use the f4,f7 buttons to do it on my keyboard. Can anyone help ?
I have an easy question which concerns the flow of execution : http://www.openbookproject.net/thinkcs/python/english3e/functions.html
I'm referring to the following paragraph :
In PyScripter, we can watch the flow of execution by “single-stepping” through any program. PyScripter will highlight each line of code just before it is about to be executed.
PyScripter also lets us hover the mouse over any variable in the program, and it will pop up the current value of that variable. So this makes it easy to inspect the “state snapshot” of the program — the current values that are assigned to the program’s variables.
This is a powerful mechanism for building a deep and thorough understanding of what is happening at each step of the way. Learn to use the single-stepping feature well, and be mentally proactive: as you work through the code, challenge yourself before each step: “What changes will this line make to any variables in the program?” and “Where will flow of execution go next?”
Let us go back and see how this works with the program above that draws 15 multicolor squares. First, we’re going to add one line of magic below the import statement — not strictly necessary, but it will make our lives much simpler, because it prevents stepping into the module containing the turtle code.
import turtle
__import__("turtle").__traceable__ = False
Now we’re ready to begin. Put the mouse cursor on the line of the program where we create the turtle screen, and press the F4 key. This will run the Python program up to, but not including, the line where we have the cursor. Our program will “break” now, and provide a highlight on the next line to be executed, something like this:
I don't know why, but when I press on F4 I only get my computer's options concerning the screen. Do you have any idea how I could correct this?
Thank you!

Pygame's Message-multiple lines?

I am using pygame and livewires (though I don't think that part is relevant here) to create a game. I've got the game working, but I'm trying to make something akin to a title screen before the game starts. However, it doesn't recognize when I try to make a new line appear. Here is what I have:
begin_message=games.Message(value=""" Destroy the Bricks!\n
In this game, you control a paddle,\n
controlled by your mouse,\n
and attempt to destroy all the rows of bricks.\n
Careful though, you only have 1 life.\n
Don't mess up! The game will start in\n
5 seconds.""",
size=30,
x=games.screen.width/2,
y=games.screen.height/2,
lifetime=500,
color=color.white,
is_collideable=False)
games.screen.add(begin_message)
The message appears on the screen, but the newline doesn't happen, so I can only read the first part of the message. Is there a way to make this message actually appear, or can I not use the 'Message' for this?
The livewires games.Message class cannot do this.
Going through the source code for games.Message shows that it inherits from games.Text, which has a method _create_surface(). Finally, this calls pygame.font.Font.render() to draw the text to a surface. If you look at the documentation for render(), it states
"The text can only be a single line:
newline characters are not rendered."
As for how you'd do what you want, I'd suggest making several Message objects, one for each line. Then display them on the screen one after the other.
There are several text rendering projects for pygame, on the site. Some are python modules ( that you can include the file locally, without installing. )
A more advanced one is Glyph.

Categories

Resources