I have been working on the development of a number of demonstration games using
pygame. I use these as demonstration pieces in classes that I teach.
I do my development on an older Mac using Mac OS X 10.12.6, with Python 3.6.1
and pygame (not sure how to check what version, but fairly recent). I'm
running these demo programs in IDLE.
I have built a library of user interface widgets that I use often. One of
these is a typical button widget. My button widget code shows an "up" state',
an "over" state, and a "down" state image. I have used this code for years,
and it works well. However, I have seen an odd behavior at the start of the
programs.
I finally decided to do some debugging and found that the problem is in pygame
sending the MOUSEBUTTONUP event. If I click right away after starting the
program, the MOUSEBUTTONDOWN event comes in followed quickly by a
MOUSEBUTTONUP. If I click again quickly, I get the MOUSEBUTTONDOWN event, BUT,
there is a delay of about one to three second before my code gets the related
MOUSEBUTTONUP event. Other events work fine, and I can tell that the program
is still running through the main loop (I can output a count of frames to the
shell window, and that continues to increase). The MOUSEBUTTONUP eventually
does happen after the delay. After that, all the MOUSEBUTTONUP events come in
just fine, and my code works well. Button clicks work perfectly.
Here is a minimal program (without using my interface widgets) that
demonstrates the problem. I just click on the background of the window, and
the program outputs a message to the shell when it gets the MOUSEBUTTONDOWN and
MOUSEBUTTONUP events:
import pygame
from pygame.locals import *
import sys
BACKGROUND_COLOR = (0, 180, 180)
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
FRAMES_PER_SECOND = 30
pygame.init()
window = pygame.display.set_mode([WINDOW_WIDTH, WINDOW_HEIGHT])
clock = pygame.time.Clock() # set the speed (frames per second)
counter = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
# if it is quit, the program
pygame.quit()
sys.exit()
if event.type == MOUSEBUTTONUP:
print('******* Got a MOUSEBUTTONUP *******')
if event.type == MOUSEBUTTONDOWN:
print('******* Got a MOUSEBUTTONDOWN *******')
print(counter)
counter = counter + 1
window.fill(BACKGROUND_COLOR)
pygame.display.update()
clock.tick(FRAMES_PER_SECOND) # make PyGame wait the correct amount
Here is a sample run:
I clicked the background right way (notice first matching MOUSEBUTTONDOWN and
MOUSEBUTTONUP) work fine.
Then I clicked again (got a MOUSEBUTTONDOWN right away, but notice how many
frames elapsed before the related MOUSEBUTTONUP).
After the long delay, the MOUSEBUTTONDOWN and MOUSEBUTTONUP's all work fine and
respond quickly.
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>>
RESTART: /Users/irvkalb/Desktop/PygWidgets Dev/pygame MOUSEBUTTONDOWN bug.py
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
******* Got a MOUSEBUTTONDOWN *******
18
19
******* Got a MOUSEBUTTONUP *******
20
21
22
23
24
25
26
27
28
29
30
31
******* Got a MOUSEBUTTONDOWN *******
32
33
34
35
36
37
38
39
40
41
<------------------------ Snipped 42 to 137 to save space! -------------->
138
139
140
141
142
143
144
******* Got a MOUSEBUTTONUP *******
145
146
147
148
149
150
151
152
153
******* Got a MOUSEBUTTONDOWN *******
154
******* Got a MOUSEBUTTONUP *******
155
156
157
158
159
160
161
162
163
164
165
******* Got a MOUSEBUTTONDOWN *******
166
167
168
******* Got a MOUSEBUTTONUP *******
169
170
171
I see this type of output consistently.
I am curious to know if anyone else has seen this behavior - or can reproduce
it with this simple program (you can comment out the print statement that
prints the loop counts). More importantly, is there anything that can be done
about it? Not a big problem - just an annoyance.
Irv