Reputation:
I am trying to encode a String to a QR code. Then show the QR code image on a display using python.
Here is my code:
import pyqrcode
from PIL import Image
import os
import pygame
from time import sleep
qr = pyqrcode.create("This is a string one")
qr.png("QR.png", scale=16)
pygame.init()
WIDTH = 1280
HEIGHT = 1080
scr = pygame.display.set_mode((WIDTH,HEIGHT),0,32)
img = pygame.image.load("QR.png")
scr.blit(img,(0,0))
pygame.display.flip()
sleep(3)
Now I want to display and flip the image in a loop.
I want to do it in a loop as the string ("This is a string one") is not constant. It will be updated (such as, I get string from mysql). When the string updates, I want to display the new QR code image after 3
seconds then flip it, then continue.
But when I put the code in a loop, it crashes and the image does not flip or update.
import pyqrcode
from PIL import Image
import os
import pygame
from time import sleep
while(1):
qr = pyqrcode.create("Nguyen Tran Thanh Lam")
qr.png("QR.png", scale=16)
pygame.init()
WIDTH = 1280
HEIGHT = 1080
scr = pygame.display.set_mode((WIDTH,HEIGHT),0,32)
img = pygame.image.load("QR.png")
scr.blit(img,(0,0))
pygame.display.flip()
sleep(5)
Update:
After 5 second, pygame-windows not flip. I must use Ctrl-C to Interrupt.
Traceback (most recent call last):
File "qr.py", line 18, in <module>
sleep(5)
KeyboardInterrupt
Upvotes: 0
Views: 683
Reputation: 20438
pygame.display.flip
doesn't flip the image, it updates the display/screen. To actually flip an image you have to use pygame.transform.flip
.
There are various other problems, for example you should do the initialization, call pygame.display.set_mode
and load the image before the while loop starts. After loading an image, call the convert
or convert_alpha
method to improve the blit performance:
img = pygame.image.load("QR.png").convert()
You also need to call pygame.event.pump()
or use an event loop for event in pg.event.get():
, otherwise the program will freeze because the OS thinks that your program has stopped responding.
To implement a timer you can use pygame.time.get_ticks
. time.sleep
makes your program unresponsive and should usually not be used in a game.
Here's an example:
import pygame as pg
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock() # A clock to limit the frame rate.
image = pg.Surface((100, 100))
image.fill((50, 90, 150))
pg.draw.rect(image, (120, 250, 70), (20, 20, 20, 20))
previous_flip_time = pg.time.get_ticks()
done = False
while not done:
for event in pg.event.get():
# Close the window if the users clicks the close button.
if event.type == pg.QUIT:
done = True
current_time = pg.time.get_ticks()
if current_time - previous_flip_time > 1000: # 1000 milliseconds.
# Flip horizontally.
image = pg.transform.flip(image, True, False)
previous_flip_time = current_time
screen.fill((30, 30, 30))
screen.blit(image, (100, 200))
# Refresh the display/screen.
pg.display.flip()
clock.tick(30) # Limit frame rate to 30 fps.
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Upvotes: 2