Cursor flashing with Tkinter and Pygame integrated in one window

Viewed 368

Below is some code I'm testing to integrate Tkinter and Pygame together. I've managed to get a pygame display inside a Tkinter window, and also show a button ontop of this pygame display. The button simply draws a white circle. The problem starts immediately by not drawing Tkinter's configured cursor (X_cursor) when the program starts. Then, when I mouse over the button and back off of it the cursor starts to flash to pygame's default cursor and then back to Tkinter's configured cursor. Also, the cursor only reverts to pygame's default if the mouse is in motion. Otherwise, it's the correct "X_Cursor".

I'm having a hard time understanding Tkinter's system, and I'm sure the solution is in my face. I just need a little help figuring it out.

import pygame
import pygame.key
from pygame.locals import *
import tkinter as tk
from tkinter import *
import os


#colors#
BLACK = (0,0,0)
WHITE = (255, 255, 255)
GREEN = (0, 255,0)
RED = (255, 0,0)
BLUE = (0,0, 255)

#buttons#
mButton1 = (1, 0, 0)
mButton2 = (0, 1, 0)
mButton3 = (0, 0, 1)



root = tk.Tk()
root.attributes('-fullscreen', True)
root.title("This title isn't visible since it's fullscreen")
root.config(cursor = "X_cursor")

embed = tk.Frame(root, width = 1920, height = 1080) #creates embed frame for pygame window
embed.grid(columnspan = 10, rowspan = 10) # Adds grid



os.environ['SDL_WINDOWID'] = str(embed.winfo_id())


worldWindow = pygame.display.set_mode((0,0), RESIZABLE)
worldWindow.fill(BLACK)


def draw():
    pygame.draw.circle(worldWindow, WHITE, (250,250), 125)

IMAGEOBJECT = PhotoImage( file = 'TESTIMAGE.gif')


buttonwin = tk.Frame(root, width = 75, height = 75)
buttonwin.grid(row =8, column = 8)
button1 = Button(root, image = IMAGEOBJECT,text = "Draw a circle", cursor = "circle",  command=draw)
button1.grid(row =8 , column = 8)



pygame.display.init()

#loop until user clicks close button
done = False

clock = pygame.time.Clock()

#~~~~~~~~MAIN LOOP~~~~~~~~#
while not done:
    for event in pygame.event.get():
        if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and pygame.K_ESCAPE):
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:  
            mButton = pygame.mouse.get_pressed()
            if mButton == mButton1:
                pos = pygame.mouse.get_pos()
                print(pos)

        else:
            pygame.event.clear()

    #limit to 60 frames per second
    clock.tick(60)

    #update the screen with all the draws
    pygame.display.update()
    root.update()
pygame.quit()
1 Answers

It appears to be tkinter and pygame 'fighting' over who shows the cursor. I added this to the pygame event loop to check.

elif event.type == pygame.MOUSEMOTION:
        pygame.mouse.set_cursor(*pygame.cursors.diamond)

The behavior stays the same, now showing the diamond cursor while moving and 'X' Cursor when stopped. When I comment out the tkinter cursor config, I then get the windows os default cursor when motion is stopped.

The easiest solution in my mind would be to load the tkinter 'X' into pygame cursor compiler and use that as its default or under the Mouse motion event (details in link).

https://www.pygame.org/docs/ref/cursors.html

Another option I kinda liked the look of, would be to use this cursor in the mouse motion elif.

*pygame.cursors.broken_x
Related