Force Focus in Tkinter

A

annagel

I am looking for a way to force a Tkinter window into focus on a system
level. I know the force focus method should bring one window of my
application into focus, but it seems I need to have some part of my
application already in focus on a system level to make this work. If
for example I am entering text at the command line and call a
force_focus on my root window the call will not return till I click on
a window in my application. The same goes for any modification to the
main window I have tried adding new windows (toplevel), setting focus,
generating events, none of these calls returns until I move focus over
to my parrent window. Is there any way around this? Basically any way
to create a kind of panic dialog that jumps up over what the user is
doing at the command line.
 
S

Steve Holden

annagel said:
I am looking for a way to force a Tkinter window into focus on a system
level. I know the force focus method should bring one window of my
application into focus, but it seems I need to have some part of my
application already in focus on a system level to make this work. If
for example I am entering text at the command line and call a
force_focus on my root window the call will not return till I click on
a window in my application. The same goes for any modification to the
main window I have tried adding new windows (toplevel), setting focus,
generating events, none of these calls returns until I move focus over
to my parrent window. Is there any way around this? Basically any way
to create a kind of panic dialog that jumps up over what the user is
doing at the command line.
Before discussion *how* to do this, are you *really* sure you want to? I
have always found it a freadful failing of the Windows interface that it
can suddenly snatch the focus away from what I am doing and force my
keystrokes and/or mouseclicks into another application.

It's worst when a dialog box appears just before I hit the ENTER key -
the ENTER acts as a button press on the dialog's default button and I
have no idea whether I just cancelled some actions or agreed to it.

regards
Steve
 
A

annagel

Thanks for the reply and as it turns out no I don't think I really do
want to do this. I started working with tkinter after banging my head
against the wall for a while with wxwindows so the whole thing ended up
being a last minute change so I am trying to get most at least of the
bugs out on a tighter scedule than I planned. Basically coming from wx
I had it in my head that I had to call a main loop or nothing would
work and this meant threads which meant all kinds of extra headaches.
In my desperation I dropped the whole thing and just started opening
windows and to my utter suprise it worked.

Now I just initialize a root window in my import statement withdraw it
and let the user use a picture viewer I made with a toplevel window, a
file chooser, folder chooser, and color chooser. I am still having a
couple problems though if anyone out there can shed some light I would
be apreciative. First the ColorChooser for some reason this dialog
does not open on its own. I am running on Mac and calling it gets my
python icon bouncing but it does not appear till I go click on the
icon. Second I am getting phantom window return with the folder and
file picker. If I have used one of these before showing the picture
viewer and then pop that up when I click on the picture window I also
get the most recent file dialog (filenameopen or directoryopen) as an
unresponsive window.

Any advice on either of those problems would be great. Sorry about the
intial post in my head I knew doing something like that would just be
evil, but you start to think crazy when your sollution is too
complicated for the problem.

Andrew
 
M

Martin Franklin

annagel said:
Thanks for the reply and as it turns out no I don't think I really do
want to do this. I started working with tkinter after banging my head
against the wall for a while with wxwindows so the whole thing ended up
being a last minute change so I am trying to get most at least of the
bugs out on a tighter scedule than I planned. Basically coming from wx
I had it in my head that I had to call a main loop or nothing would
work and this meant threads which meant all kinds of extra headaches.
In my desperation I dropped the whole thing and just started opening
windows and to my utter suprise it worked.

Now I just initialize a root window in my import statement withdraw it
and let the user use a picture viewer I made with a toplevel window, a
file chooser, folder chooser, and color chooser. I am still having a
couple problems though if anyone out there can shed some light I would
be apreciative. First the ColorChooser for some reason this dialog
does not open on its own. I am running on Mac and calling it gets my
python icon bouncing but it does not appear till I go click on the
icon. Second I am getting phantom window return with the folder and
file picker. If I have used one of these before showing the picture
viewer and then pop that up when I click on the picture window I also
get the most recent file dialog (filenameopen or directoryopen) as an
unresponsive window.

Any advice on either of those problems would be great. Sorry about the
intial post in my head I knew doing something like that would just be
evil, but you start to think crazy when your sollution is too
complicated for the problem.

Andrew

Andrew,

Glad to hear you got it working, could you post some example code that
shows these other problems?


Martin
 
S

Steve Holden

annagel said:
Thanks for the reply and as it turns out no I don't think I really do
want to do this. I started working with tkinter after banging my head
against the wall for a while with wxwindows so the whole thing ended up
being a last minute change so I am trying to get most at least of the
bugs out on a tighter scedule than I planned. Basically coming from wx
I had it in my head that I had to call a main loop or nothing would
work and this meant threads which meant all kinds of extra headaches.
In my desperation I dropped the whole thing and just started opening
windows and to my utter suprise it worked.
It may well be that you will need to use threads anyway, I'm afraid -
ultimately if you want computation to keep on happening while the GUI
remains responsive then it's almost a requirement. However, it's easier
to make a start when you are actually seeing windows appear on the
screen, so I'm glad you are making progress.
Now I just initialize a root window in my import statement withdraw it
and let the user use a picture viewer I made with a toplevel window, a
file chooser, folder chooser, and color chooser. I am still having a
couple problems though if anyone out there can shed some light I would
be apreciative. First the ColorChooser for some reason this dialog
does not open on its own. I am running on Mac and calling it gets my
python icon bouncing but it does not appear till I go click on the
icon. Second I am getting phantom window return with the folder and
file picker. If I have used one of these before showing the picture
viewer and then pop that up when I click on the picture window I also
get the most recent file dialog (filenameopen or directoryopen) as an
unresponsive window.
It's probable that you are failing to destroy some widget after use, but
that's about as much as I can say at present.
Any advice on either of those problems would be great. Sorry about the
intial post in my head I knew doing something like that would just be
evil, but you start to think crazy when your sollution is too
complicated for the problem.
As Martin has indicated, more detail in the form of code will be
necessary to investigate specific problems like that.

In practice the choice between Tkinter and wxPython, PyGtk and the like
is often either a religious issue or a choice based on the first tool
that could be manipulated to providing the required results. Ideally you
want to structure your program so that the GUI can be changed without
too much effect on the rest of the logic, though that's often easier
said than done.

regards
Steve
 
A

annagel

OK some sample Code. First from the module that I am importing. I
won't post anything because the vast majority of stuff is way outside
the scope of this problem and has to do with image and sound
manipulation.

First the imports I use:

import sys
import os
import user
import traceback
import time
import Numeric
import struct
from Image import *
from threading import *
from math import sqrt
import cStringIO
from Tkinter import *
from Queue import *
import thread
import ImageTk
import tkFileDialog
import tkColorChooser
import pygame

#Now some initialization
ver = "1.1"
pygame.mixer.pre_init(22050, -16, False)
pygame.init()
defaultFont = pygame.font.SysFont("times", 24)

top = Tk()

mediaFolder = user.home + os.sep


#Some global functions that use the file and color dialogs

def pickAFile(**options):
path = tkFileDialog.askopenfilename()
return path

def pickAFolder(**options):
global mediaFolder
folder = tkFileDialog.askdirectory()
if folder == '':
folder = mediaFolder
return folder

def pickAColor(**options):
color = tkColorChooser.askcolor()
newColor = Color(color[0][0], color[0][1], color[0][2])
return newColor

# the color object is just a container for the r, g, b values that can
also do things like
# lighten and darken it

#Finally my picture class (abreviated)

class Picture:
def __init__(self):
self.title = "Unnamed"
self.dispImage = None

def createImage(self, width, height):
self.surf = pygame.Surface((width, height))
self.pixels = pygame.surfarray.pixels3d(self.surf)
self.filename = ''
self.title = 'None'

def getImage(self):
data = pygame.image.tostring(self.surf, "RGB", 0)
image = fromstring("RGB", (self.getWidth(), self.getHeight()), data)
return image

def loadImage(self,filename):
global mediaFolder
if not os.path.isabs(filename):
filename = mediaFolder + filename
self.surf = pygame.image.load(filename)
self.pixels = pygame.surfarray.pixels3d(self.surf)
self.filename = filename
self.title = getShortPath(filename)

def repaint(self):
self.dispImage = ImageTk.PhotoImage(self.getImage())
self.item = self.canvas.create_image(0, 0, image=self.dispImage,
anchor='nw')

def show(self):
self.frame = Toplevel()
self.canvas = Canvas(self.frame, width=self.getWidth(),
height=self.getHeight())
self.dispImage = ImageTk.PhotoImage(self.getImage())
self.item = self.canvas.create_image(0, 0, image=self.dispImage,
anchor='nw')
self.canvas.pack()

#For this the Pixel class is a reference directly into the image data
so a user can modify
#the image in a pixel by pixel maner

#Convenience global function

def makePicture(filename):
picture = Picture()
picture.loadImage(filename)
try:
w = picture.getWidth()
return picture
except:
print "Was unable to load the image in " + filename +"\nMake sure
it's a valid image file."

Now the code I run and the results

When I do this I get my image window to pop-up and it works fine is
responsive to everything I do, but when I click on it I get the old
filePicker with my selection still made in it. I can't do anything at
all with this window though I still have complete control over the
picture window but nothig over this new window.

Finally the colorPicker

this starts my python icon jumping around but the picker does not
appear until after I click the jumping window and then click back to my
command prompt (I am using osx 10.4)

If anyone wants more information I would be happy to send it along. I
just did not want to post all of the code because the whole file is 900
lines long and I really do not think that most of it should matter at
all to what is going on with the windows since none of the sound stuff
used windows at all and Color and Pixel use it in that they interact
with Picture but not for any other reason.

Thanks again for any help

Andrew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,991
Messages
2,570,217
Members
46,805
Latest member
ClydeHeld1

Latest Threads

Top