0

I am searching a way to create a window in python where I can control each individual pixel. And also where I can update them live using functions. My objective here is to create a python package. So the idea would be :

import package

app = package.main()

app.init() # This would create the window
app.set_pixel(0, 0, (255, 0, 0)) # And this would set the pixel with x = 0 and y = 0 to red

I have tried with PyGame and Tkinter but they both use a main loop and all functions called after the loop started are not executed unless the app is closed.

Is there a way to do something like this where everything can be updated live ?

Escartem
  • 37
  • 1
  • 6
  • Look at tkinter's `.after` method. The syntax is: `.after(time_delay_in_ms, function_to_call)`. Tkinter automatically calls your function after the delay. – TheLizzard Jun 25 '21 at 09:46
  • Check out these answers: [Change the color of a pixel in a canvas](https://stackoverflow.com/questions/14491092/change-the-color-of-a-pixel-in-a-canvas-tkinter-python). Here are examples of manipulating images in tkinter without third-party libraries: [How to change the pixel color of a PhotoImage](https://stackoverflow.com/questions/29701852/how-to-change-the-pixel-color-of-a-photoimage-python/29730449#29730449), [How to work with pixels](https://stackoverflow.com/questions/12284311/python-tkinter-how-to-work-with-pixels). – 8349697 Jun 25 '21 at 10:43
  • The main question is: why do you need it? Do you want to create some kind of animation or pixel art or what? Look for similar packages at https://pypi.org. The source code can usually be found on GitHub. – 8349697 Jun 25 '21 at 10:47
  • what I want to do is make a recreation of a module named "kandinsky" that is only for numworks calculators and I want to make it for pc. I already know how to edit the pixels I am searching a way to update them live not in a delay. Like for example running commands from a console and see the screen update. – Escartem Jun 25 '21 at 12:14
  • Have you thought about running tkinter in a different thread? – Art Jun 25 '21 at 13:39
  • @Art That is very complicated and shouldn't be attempted unless you really know what you are doing. Parts of `tkinter` aren't threadsafe so they should never be called from different threads. Furthermore, sometimes `tkinter` can crash without giving an error/traceback. That happened to me once. It just said `TCL_PANIC`. – TheLizzard Jun 25 '21 at 13:50
  • Sounds like you want an interactive mode. You will need some kind of event listener and command interpreter for this. And, probably, the task queue. Some possible options: Use `tk.Entry` to enter commands. In this case, `tk.Entry` will be part of the program (window). – 8349697 Jun 26 '21 at 16:28
  • [Here](https://gordonlesti.com/use-tkinter-without-mainloop/) you can see how you can organize user input through the Python Shell. You can try adapting it to get interactive mode. – 8349697 Jun 27 '21 at 11:44

1 Answers1

1

There's no need to update anything oustide of the mainloop, you should run your functions inside the loop itself - the mainloop is what means that it's running live. If not, the screen won't update (that's basically the main thing the loop does - update the screen).

You could try the following in Pygame:

import pygame as pg

pg.init()

WIDTH = 1300
HEIGHT = 900

screen = pg.display.set_mode((WIDTH, HEIGHT))

# mainloop
running = True
while running:
    # event processing
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
            break

    # drawing section
    screen.set_at((1, 1), (255, 0, 0))
    pg.display.flip()

pg.quit()

the screen.set_at((x, y), (r, g, b)) function is the one that sets a specific pixel to a specific color.

EDIT: You could write a module called display that has a function that receives the function you want to run inside the mainloop and runs it. It would look like this:

import display

def func(screen):
    screen.set_at((1, 1), (255, 0, 0))

display.start(func)
Shufi123
  • 233
  • 3
  • 11
  • Yes but if I want to have the "set_at" be runned manually like from example run "set_at" from a different file ? Like this one is a package imported in a main.py where I do the "set_at" but the mainloop is still on the package. – Escartem Jun 27 '21 at 22:19
  • 1
    To my knowledge, that is impossible - there is an update loop which tells the screen to refresh (in Pygame's case, ```pg.display.flip()```). It has to refresh. The best you can do is create a module function that takes another function as a parameter and runs the function inside the mainloop, so that you would use it as detailed in the edit on the answer. – Shufi123 Jun 28 '21 at 15:52