Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

3 beginner questions!

4 views
Skip to first unread message

Ali Dada

unread,
May 6, 2003, 1:04:36 PM5/6/03
to
hi all:

first question (PyQt):
i am using the Qt designer that comes with RedHat9 to design a simple .ui form,
then i am saying:

$ pyuic form.ui > form.py

which successfully generates python code which includes a class definition that
is supposed to generate the form. i am adding a line to the code to create an
instance of the class so that i get a window or form or anything useful. when i
execute the modified code i get the following line on stdout:

QPaintDevice: Must construct a QApplication before a QPaintDevice

second question (Tkinter and Pmw)

i wrote the file below, called ScrolledListBox.py, and it works
fine when run directly from the terminal (ie it brings up a ScrolledListBox with
three entries so that when you select any of them it performs it function
properly, writing 'hi' to stdout)


#!/usr/bin/env python
from Tkinter import *
import Pmw

class ImageSelection(Frame ):

def __init__( self):
root = Tk()
Frame.__init__( self )
Pmw.initialise()
self.pack( expand = YES, fill=BOTH)
self.suites=['a', 'b', 'c']
self.listBox = Pmw.ScrolledListBox( root, items = self.suites, listbox_height
= 5, vscrollmode = "static", selectioncommand = self.switchSuite)
self.listBox.pack( side = LEFT, expand = YES, fill= BOTH, padx = 5, pady=5)

def switchSuite(self):
print 'hi'

def main():
ImageSelection().mainloop()


if __name__ == "__main__":
ImageSelection().mainloop()


now the problem comes. i need to call the above from a new file called
Index.py, shown below. Index.py imports ScrolledListBox and makes a Button that
calls ScrolledListBox. surprisingly (for me at least) the three entries in the
ListBox don't perform as expected.

#!/usr/bin/env python
from Tkinter import *
import ScrolledListBox

class Index(Frame):
def __init__(self, parent=None):

Frame.__init__(self, parent)
Button(self, text='Regression', command=ScrolledListBox.main).pack(side=TOP,
fill=BOTH)


if __name__ == '__main__':
i = Index()
i.pack()
i.mainloop()

third question (Tkinter):

i am programming a menu bar that should appear alone in the window and should
span the width of the screen and should be displayed at the top of the screen.
any idea how this should be implemented? if i am not expressing myself properly,
i pasted my trial below.


#!/usr/bin/env python

from Tkinter import * # get widget classes
from tkMessageBox import *
import sys
import OpenWorkArea
# get standard dialogs
class CMmenu(Frame):
def __init__(self,parent=None) :
Frame.__init__(self, parent)
self.pack()
widget = Button(self, text='Code Manage', command= self.makemenu)
widget.pack(side=LEFT)

def makemenu(self):
root = Tk()
root.title('TAGZ -- Code Manage')
top = Menu(root) # win=top-level window
root.config(menu=top)
WorkArea = Menu(top, tearoff=0)
WorkArea.add_command(label='Open...', command =
OpenWorkArea.WorkAreaSelection, underline=0)
WorkArea.add_separator()
WorkArea.add_command(label='Close', command=root.quit, underline=0)
WorkArea.add_command(label='Release...', command=self.notdone, underline=0)
WorkArea.add_separator()
WorkArea.add_command(label='Commit Files...', command=self.notdone, underline=0)
WorkArea.add_command(label='Update Files...', command=self.notdone, underline=0)
WorkArea.add_command(label='Restore Version...', command=self.notdone,
underline=0)
WorkArea.add_command(label='Tag Files...', command=self.notdone, underline=0)
WorkArea.add_separator()
WorkArea.add_command(label='Refresh', command=self.notdone, underline=0)
top.add_cascade(label='Work Area', menu=WorkArea, underline=0)

file = Menu(top, tearoff=0)
file.add_command(label='Open', command=self.notdone, underline=0)
file.add_separator()
file.add_command(label='Commit...', command=self.notdone, underline=0)
file.add_command(label='Update', command=self.notdone, underline=0)
file.add_command(label='Restore Version...', command=self.notdone,
underline=0)
file.add_command(label='Tag...', command=self.notdone, underline=0)
file.add_command(label='Open Differences', command=self.notdone, underline=0)
file.add_separator()
file.add_command(label='Delete and Update...', command=self.notdone,
underline=0)
file.add_separator()
file.add_command(label='Add to Work Area', command=self.notdone, underline=0)
file.add_command(label='Add to Work Area as Binary', command=self.notdone,
underline=0)
file.add_command(label='Remove from Work Area', command=self.notdone,
underline=0)
file.add_separator()
file.add_command(label='Refresh', command=self.notdone, underline=0)
top.add_cascade(label='File', menu=file, underline=0)

edit = Menu(top, tearoff=0)
edit.add_command(label='Undo', command=self.notdone, underline=0)
edit.add_command(label='Redo', command=self.notdone, underline=0)
edit.add_separator()
edit.add_command(label='Cut', command=self.notdone, underline=0)
edit.add_command(label='Copy', command=self.notdone, underline=0)
edit.add_command(label='Paste', command=self.notdone, underline=0)
edit.add_command(label='Delete', command=self.notdone, underline=0)
edit.add_command(label='Select All', command=self.notdone, underline=0)
edit.add_separator()
top.add_cascade(label='Edit', menu=edit, underline=0)

find = Menu(edit, tearoff=0)
find.add_command(label='Find...', command=self.notdone, underline=0)
find.add_command(label='Find Next', command=self.notdone, underline=0)
find.add_command(label='Find Previous', command=self.notdone, underline=0)
find.add_command(label='Use Selection for Find', command=self.notdone,
underline=0)
find.add_command(label='Jump to Selection', command=self.notdone, underline=0)
edit.add_cascade(label='Find', menu=find, underline=0)
tools = Menu(top, tearoff=0)
inspector = Menu(tools, tearoff=0)
inspector.add_command(label='Status', command=self.notdone, underline=0)
inspector.add_command(label='Logs', command=self.notdone, underline=0)
inspector.add_command(label='Differences', command=self.notdone, underline=0)
inspector.add_command(label='Tags', command=self.notdone, underline=0)
inspector.add_command(label='Contents', command=self.notdone, underline=0)
tools.add_cascade(label='Inspector', menu=inspector, underline=0)
repositories = Menu(tools, tearoff=0)
repositories.add_command(label='??', command=self.notdone, underline=0)
repositories.add_command(label='???', command=self.notdone, underline=0)
repositories.add_command(label='????', command=self.notdone, underline=0)
repositories.add_command(label='?????', command=self.notdone, underline=0)
repositories.add_command(label='??????', command=self.notdone, underline=0)
tools.add_cascade(label='Repositories', menu=repositories, underline=0)
tools.add_command(label='Processes', command=self.notdone, underline=0)
tools.add_command(label='Comparisons...', command=self.notdone, underline=0)
console = Menu(tools, tearoff=0)
console.add_command(label='??', command=self.notdone, underline=0)
console.add_command(label='???', command=self.notdone, underline=0)
console.add_command(label='????', command=self.notdone, underline=0)
console.add_command(label='?????', command=self.notdone, underline=0)
console.add_command(label='??????', command=self.notdone, underline=0)
tools.add_cascade(label='Console', menu=console, underline=0)
top.add_cascade(label='Tools', menu=tools, underline=0)

window= Menu(top, tearoff=0)
window.add_command(label='Close Window', command=root.quit, underline=0)
top.add_cascade(label='Window', menu=window, underline=0)

help= Menu(top, tearoff=0)
help.add_command(label='About...', command=self.notdone, underline=0)
help.add_command(label='TAGZ Manual', command=self.notdone, underline=0)
top.add_cascade(label='Help', menu=help, underline=0)
def notdone(self):
showerror('Not implemented', 'Not yet available')
if __name__ == '__main__':

#makemenu(root)
CMmenu().mainloop()

Alex Martelli

unread,
May 6, 2003, 2:36:52 PM5/6/03
to
Ali Dada wrote:

> hi all:
>
> first question (PyQt):
> i am using the Qt designer that comes with RedHat9 to design a simple .ui
> form, then i am saying:
>
> $ pyuic form.ui > form.py
>
> which successfully generates python code which includes a class definition
> that is supposed to generate the form. i am adding a line to the code to
> create an instance of the class so that i get a window or form or anything
> useful. when i execute the modified code i get the following line on
> stdout:
>
> QPaintDevice: Must construct a QApplication before a QPaintDevice

Don't modify the files generated by pyuic -- they'll be overwritten
next time you change the .ui file and regenerate the .py! Rather,
if you need changes, do them by inheritance after importing the file.

Before *instantiating* widgets, you need to instantiate QApplication.
Did you do that...?


Alex

Ali Dada

unread,
May 6, 2003, 4:37:32 PM5/6/03
to
>
> Before *instantiating* widgets, you need to instantiate QApplication.
> Did you do that...?

nope! how should i do that (i should give it an argument but i don't
know the type of this argument) and where should i do that (seperate
file than that generated?)

thanks..

Rune Hansen

unread,
May 7, 2003, 10:20:43 AM5/7/03
to
Ali Dada wrote:
> hi all:
>
> first question (PyQt):
> i am using the Qt designer that comes with RedHat9 to design a simple .ui form,
> then i am saying:
>
> $ pyuic form.ui > form.py
>
> which successfully generates python code which includes a class definition that
> is supposed to generate the form. i am adding a line to the code to create an
> instance of the class so that i get a window or form or anything useful. when i
> execute the modified code i get the following line on stdout:
>
> QPaintDevice: Must construct a QApplication before a QPaintDevice

First of all you should use pyuic like this:
$ pyuic -x -o form.py form.ui
$ python form.py - should start your GUI. If not, you may have a pyuic
version with the "image" bug or an otherwise defective PyQt instalation.
Secondly, as Alex pointed out, use form.py by inheritance since it's
more than likely you'll want to edit form.ui in designer at some point.
If the problem persists after updating PyQt you'll have to post some code.

Yet again a question of inheritance. Personally I would have written it
along these lines:
--
--ScrolledListBox.py


#!/usr/bin/env python
from Tkinter import *
import Pmw

class ImageSelection(Frame ):
def __init__( self):

Frame.__init__( self )
root = Tk()
Pmw.initialise()

self.pack( expand = YES, fill=BOTH)
self.suites=['a', 'b', 'c']
self.listBox = Pmw.ScrolledListBox( root, items = self.suites,

listbox_height= 5, vscrollmode = "static", selectioncommand =

self.switchSuite)
self.listBox.pack( side = LEFT, expand = YES, fill= BOTH, padx
= 5, pady=5)

def switchSuite(self):
print 'hi

--Start.py


#!/usr/bin/env python
from Tkinter import *

from ScrolledListBox import ImageSelection

class ImageSel(ImageSelection):
def __init__(self):
ImageSelection.__init__(self)

class Index(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
Button(self, text='Regression',

command=self.buttonOpensImageSelectionWindow).pack(side=TOP,fill=BOTH)

def buttonOpensImageSelectionWindow(self):
_w = ImageSel()
_w.mainloop()

if __name__ == '__main__':
i = Index()
i.pack()
i.mainloop()

Not necessarily the best or most correct way, but it should at least get
you facing in the right general direction.

/rune

Alex Martelli

unread,
May 7, 2003, 5:53:46 PM5/7/03
to
<posted & mailed>

Ali Dada wrote:

The general pattern is:

import sys
import qt

# make the application object (it needs the list of arguments)
app = qt.QApplication(sys.argv)

# ensure the application ends when its last window is closed
qt.QObject.connect(a,qt.SIGNAL('lastWindowClosed()'),a,qt.SLOT('quit()'))

# let's see the form that lives in myform.py
import myform
form = myform.Form1()
app.setMainWidget(form)
form.show()
app.exec_loop()


That's all! You don't need to alter myform.py to display the form, etc.


Actually, pyuic has several handy switches, one of which basically
generates this "let's see the form" code as a part of form.py --
AND nicely protected, as Python idiom requires, by a guard of the form

if __name__ == '__main__':

so that the "let's see the form" code won't execute if what you're doing
is (normal case) IMPORTING the form module -- only if you're RUNNING this
generated Python file as the main script!


So, a command such as:

pyuic -x myform.ui > myform.py

will make you a Python script myform.py which, as well as importing for
use by a program, you can ALSO execute directly with

python myform.py

in order to see the form it contains.


Run:

pyuic -help

for a summary of pyuic's handy commandline options.


Alex

Ali Dada

unread,
May 7, 2003, 7:16:22 PM5/7/03
to
thanks all for your ideas on PyQt: they got me going!!

but the problem with Tkinter (question 2) is still not solved. i
tested Rene's code but it still didn't work. and by the way, i tried
to run a PyQt-generated window from a Tkinter window but the former
messes up the latter and rendered it unusable. any ideas on mixing the
two libraries in my application or is it an unrecommended approach??
thanks again for your help!!

Rune Hansen <rune....@viventus.no> wrote in message news:<b9b482$8or$1...@services.kq.no>...


> Ali Dada wrote:
> > hi all:
> >

Chad Netzer

unread,
May 7, 2003, 8:33:45 PM5/7/03
to
On Tue, 2003-05-06 at 10:04, Ali Dada wrote:

> second question (Tkinter and Pmw)

Don't take this the wrong way, but because of limited time, I'm just
going to give you some basic advice, and then show you the application
as it should be written:

1) Don't call your file ScrolledListBox.py, because you are using a
Pmw.ScrolledListBox and things will be confusing (besides, you aren't
defining a ScrolledListBox in it at all; your module should be named
after what it ultimately wants to do, even just "app.py" would be
better)

2) You want to call Tk() once, in the main section. Similar to the
mainloop(). You should NOT call either of these in object methods; my
example below will show you what I mean. Notice that the mainloop() is
the last function that the python interpreter enters... It is called
once, and doesn't return until the user somehow destroys the root window
(ie. exits the program). Within the mainloop(), Tk is executing and
handling all the "events" that occur (button presses, mouse moves,
window events, etc.)

3) If you call Pmw.initialise(), this will initialize Tk for you (ie. it
does a Tk() call, and returns the result, among other things.)

4) You should give your subject line more details (ie. at the VERY leats
mention Tkinter; I missed it the first time because I didn't scroll down
to your second question, and had no idea there was any Tkinter content
in your original post)

5) Index is much too general a name for a class, unless it is
unambiguously part of a larger framework. I called it ImageIndex, which
is marginally better.

6) Check out <a
href="http://home.att.net/~stephen_ferg/thinking_in_tkinter/">Thinking
in Tkinter</a> by Steve Ferg, if you haven't already. Your career with
Tkinter will be MUCH happier.

7) Do not EVER derive from a Frame widget, and then pack that widget in
the __init__() method. A widget should NOT pack itself. The Frame
widget you derive from does not pack() itself, and since you are
deriving ImageSelection from a Frame widget, it is ALSO a Frame widget.
And thus you leave it up to the code that instantiates that widget to
pack it. This is *THE NUMBER ONE* mistake that new Tkinter users make,
and although it seems unimportant, you should unlearn it now. What
happens when you try to use that widget and put it in a gridded frame?
Your application crashes.

Here is a rewitten version of your original program. It is all in one
file. This does what your original program attempted to do, but is
still not perfect. For example, see what happens when the "Regression"
button is pressed multiple times? You can deal with these issues once
you understand the changes I made:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#!/usr/bin/env python
from Tkinter import *

import Pmw

class ImageSelection(Frame):
def __init__( self):

Frame.__init__(self)

self.suites=['a', 'b', 'c']

widget = Pmw.ScrolledListBox
self.listBox = widget(root,


items = self.suites,
listbox_height = 5,
vscrollmode = "static",
selectioncommand = self.switchSuite)
self.listBox.pack(side=LEFT, expand=YES, fill=BOTH,
padx=5, pady=5)

return

def switchSuite(self):
print 'hi'

class Index(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)

button = Button(self, text='Regression',
command=self.button_func)
button.pack(side=TOP, fill=BOTH)
return

def button_func( self ):
image_selection = ImageSelection()
image_selection.pack(expand = YES, fill=BOTH)
return


if __name__ == "__main__":
root = Pmw.initialise()

image_index = Index()
image_index.pack()

root.mainloop()


> third question (Tkinter):
>
> i am programming a menu bar that should appear alone in the window and should
> span the width of the screen and should be displayed at the top of the screen.
> any idea how this should be implemented?

Well, your third example is WAY too much code for me to even look at.
I'd suggest you post a small example with the minimal attempt at what
you want. In the meantime, I'll say that if you want the menubar to
appear at the top of the screen, and NOT at the top of your application
window, this behavior depends on the system you are running on. It'll
work on Macs, for example, but Windows doesn't work this way. If you
want it at the top of your applicatin window, then keep trying after
looking at more Tkinter examples on the Web or search for my old
postings on Google. For example, search Google groups for "Chad Netzer
tkinter menubar".


--

Chad Netzer
(any opinion expressed is my own and not NASA's or my employer's)


0 new messages