When I'm using Pygame, a python library, I have to write "pygame.init" to initiate all modules. However, when I'm using Tkinter, another library, I don't have to use "tkinter.init". Why?
Thanks!
When I'm using Pygame, a python library, I have to write "pygame.init()" to initiate all modules. However, when I'm using Tkinter, another library, I don't have to use "tkinter.init()". Why?
Each Python library comes with its own way of using it and own mechanisms implemented for event handling if the library provides methods for interacting with the user.
How to use the library is then explained in the documentation or can be inferred from the documentation coming along with each library method and printed on demand.
So the right answer to the question why you have to use the library this and not other way is as simple as maybe surprising:
Because the library requires to use it this and not other way.
By the way:
in Tkinter (newer versions of the module are named tkinter) the initialization is silently done within an initialization method __init__ of the class Tk when creating the root window with root = tkinter.Tk() and for the tkinter window coming up you need in addition to this initialization tkinter.mainloop().
Here a minimal tkinter code required to open a window (see comments for details/explanations):
import tkinter
root = tkinter.Tk()
tkinter.mainloop()
# ^-- requires root = tkinter.Tk() else:
# ^-- RuntimeError: Too early to run the main loop: no default root window
in pygame it is not necessary to call pygame.init() to open a pygame window.
Here a minimal pygame code required to open a window, keep it opened and responding (see comments for details/explanations):
import pygame
# pygame.init()
# ^-- is NOT required
screen = pygame.display.set_mode((640,480))
# ^-- REQUIRED else: pygame.error: video system not initialized
# ^-- creates the pygame window which stays opened (but not responding)
# ^-- as long as the Python script runs
# v--REQUIRED to keep the pygame window opened and responding:
running = True
while running:
# Check for exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Related
So I'm following the alien invasion project from python crash course, at the beginning the book teaches how to open a simple window with a specific background color. I literally copy-pasted the code from the book and it still does not work.
import pygame
import sys
from settings import Settings
def run_game():
# Initialize game and create a screen object.
pygame.init()
# Init settings
my_settings = Settings()
screen = pygame.display.set_mode((my_settings.screen_widht, my_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# Start the main loop for the game.
while True:
# Watch for keyboard and mouse events.
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Redraw the screen during each pass through the loop.
screen.fill(my_settings.bg_color)
# Make the most recently drawn screen visible.
pygame.display.flip()
run_game()
EDIT: To clarify, I'm not saying the code doesn't work, it works without errors but takes a minute to open... it's something with my system, but I don't know what it is, that's why I'm asking
Edit2: I realized that if I remove pygame.init() the window opens instantly, not sure what it means
pygame.init() initializes all pygame modules. This may take some time on some systems. If you don't need all pygame modules, just leave it out. For the display and event handling it is not necessary to call pygame.init() at all. If you need other modules, you can itialize them separately (e.g. pygame.font.init(), pygame.mixer.init()).
See pygame.init()
Initialize all imported pygame modules. No exceptions will be raised if a module fails, but the total number if successful and failed inits will be returned as a tuple. You can always initialize individual modules manually, but pygame.init()initialize all imported pygame modules is a convenient way to get everything started. The init() functions for individual modules will raise exceptions when they fail.
You may want to initialize the different modules separately to speed up your program or to not use modules your game does not require.
"You've pressed the Enter Key!"
Whenever I press Key(z) the function should be executed:
#Pseudocode:
bind(<Enter>, function_x)
I'm currently working on a python program, which will run in a constant loop. It runs only on the console (no GUI), but still I need to be able to interact with the program at any time without having the program asking for input.
Several Modules solve this Problem
Pynput
(pip install pynput)
Simple module for handling and controlling general inputs
from pynput import keyboard
from pynput.keyboard import Key
def on_press(key):
#handle pressed keys
pass
def on_release(key):
#handle released keys
if(key==Key.enter):
function_x()
with keyboard.Listener(on_press=on_press,on_release=on_release) as listener:
listener.join()
(See pynput docs)
Keyboard (pip install keyboard)
A simple module for simulating and handling keyboard input
keyboard.add_hotkey('enter', lambda: function_x())
(See Keyboard docs)
Tkinter
Integrated UI Module, can track inputs on focused thread
from tkinter import Tk
root = Tk() #also works on other TK widgets
root.bind("<Enter>", function_x)
root.mainloop()
Be aware: These solutions all use Threading in some way. You might not be able to execute other code after you've started listening for keys.
Helpful threads:
KeyListeners, Binding in Tkinter
feel free to add more solutions
No beans with module keyboard.
Simply way to clear screen:
print('\033[2J') # clear screen, but stay current cursor line
print('\033[H') # move cursor 1,1 home position
or
print('\033[H\033[2J') # one step to clear screen and move at home position
You may define function like:
def cls():
print('\033[H\033[2J')
It works with tedious call braces.
I like to bind previous functionality to keyboard 'scroll lock' key, but how?
I'm using pygame for my game and its online but the problem is that whenever the main loop of the game waits for the socket from the server its freezes.
so unless you are doing your turn, the client wait for a socket from the server and its doing nothing while waiting and freeze until its get the socket and do its turn.
So I read few answers and solutions on this site and on some others and from what I understood after 5 seconds of doing nothing the OS thinks the window (locked itself)? so I created the thread keep_run but it does not make any change and the window still freeze while its not his turn.
Also to mention the server works with select library if its help in anyway because keep_run() is the only thread I used.
I did not include many lines in my code because there are too much but its a basic conclusion of the important stuff that maybe cause it?
import sockets
import pygame
from threading import Thread
def keep_run():
clock = pygame.time.Clock()
fps = 60
while True:
pygame.event.pump()
clock.tick(fps)
pygame.init()
keep_running = Thread(target=keep_run)
keep_running.setDaemon(True)
keep_running.start()
while Game_run:
#the main loop
server_command = client_socket.recv(1024)
if server_command == "move":
# make your turn
do_turn()
elif server_command == "over":
# finish the game
finish_game()
image of the example: https://i.stack.imgur.com/b4Qx8.png
You must call pygame.event.pump() (which is implicitly called by pygame.event.get(), pygame.event.clear(), pygame.event.poll(), pygame.event.wait() or pygame.event.peek()) regularly in the thread that initialized the video subsystem (Pygame is built on SDL, hence the link to SDL documentation).
I would also suggest that you don't use pygame.event.pump() and instead handle all events properly with pygame.event.get() or pygame.event.poll(). More about this here.
In every pySLD2 example I've found, I've seen a loop at the end of the code to keep the window open until closure. For example:
#!/usr/bin/env python
"""
The code is placed into public domain
by anatoly techtonik <techtonik#gmail.com>
"""
import sdl2
import sdl2.ext as lib
lib.init()
window = lib.Window('', size=(300, 100))
window.show()
renderer = lib.Renderer(window)
renderer.draw_point([10,10], lib.Color(255,255,255))
renderer.present()
####Specifically this loop####
running = True
while running:
for e in lib.get_events():
if e.type == sdl2.SDL_QUIT:
running = False
break
if e.type == sdl2.SDL_KEYDOWN:
if e.key.keysym.sym == sdl2.SDLK_ESCAPE:
running = False
break
All event handlers I've seen have been blocking. Is there a way, like I have seen done in standard SDL, to simply call initialization and updating functions on a window that stays open. I am writing to write this as an external library that I can call independently from any project.
Any ideas? Thanks!
EDIT: As per request for a way to do this in standard SDL, this works. Just call the init function to set up the screen and it will stay until you close it.
You are misinterpreting the example - this is an additional hook (screen.c) to be set up in the main loop.
SDL uses the main loop approach to deal with events, update the window display, etc. Yes, there is a way to work around that. Create your very own window and use whatever approach to keep it open, get the window handle via the SDL_SysWM* functions and update the window's display buffer.
This however involves some glue code and also requires you to do the window handling on your own.
I'm trying to use Snack to make a simple mp3 player. It works together with Tkinter. Here is what documentation says about its usage:
The beginning of a program that uses Snack might look like:
from Tkinter import *
root = Tk()
import tkSnack
tkSnack.initializeSnack(root)
# Now you can use tkSnack commands and objects
# ...
The root = Tk() line opens an empty window, which could be closed after the initialization of Snack and Snack will continue to work the same (paying, pausing, resuming, loading audios and so on).
Is there any way to avoid the opening of this window? May you explain why such a library needs a graphical window in order to work?
If you use root = Tk().withdraw() then the Tk window will be created but not displayed. Hopefully it will not even flash on screen.
The Tcl snack package is a Tk extension and has a number of commands that call Tk functions. So the original design just didn't break it into windowing and non-windowing sections. However Tk is not required to use snack, but you must run an event loop at some point. For instance in a Tcl script (no Tk) you can do:
package require snack
snack::sound snd -file $filename
snd play -blocking 0
after 5000 {set waiting 1}
vwait waiting
This will setup a snd command with the file data configured and then tell it to play. However, nothing will happen until we start the event loop (vwait waiting) and in this case we schedule something to happen in 5 seconds to time the wait out.
Looking at the tkSnack sources can probably help you translate the above into something pythonic. They are just a wrapper around the Tcl/Tk package. But I suspect running the Tk window will help in getting the music playing.
You can use root.withdraw() method to hide your window.
Optionally, if you are ever planing to use it again, use root.deiconify()