¿Como añadir un scrollbar a una ventana muy grande?(Python)

Iniciado por XD YO, 13 Febrero 2010, 02:49 AM

0 Miembros y 1 Visitante están viendo este tema.

XD YO

Antes que nada Buenas noches a todos ;)

Siguiendo trabajando, la ventana que cree utilizando Tkinter ha quedado demasiado grande para la resolución de pantalla y pensé en añadir un scrollbar a un costado para hacerla mas pequeña y menos molesta; pero, después de estar gogleando durante un buen rato, la única información que encuentro (tanto en español como en ingles) solo dice como utilizarlo cuando se trata de una ventana ocupada completamente por un textarea o una lista muy grande; pero no dice como utilizarlo si lo que estoy manejando en la ventana son un conjunto de labels, textentris, radiobutons y/o butons.

¿Alguna idea de lo que se puede hacer?  :rolleyes:

De antemano, gracias por su tiempo.  ;)
"Fácilmente aceptamos la realidad, acaso porque intuimos que nada es real"
-Borges -El inmortal

^Tifa^

Explicate que es eso de labels, textentries, etc, etc....

Porke puedes perfectamente colar botones, labels, lo que sea en una misma ventana en conjunto con un Textarea:

Código (python) [Seleccionar]

from Tkinter import *

root = Tk()
frama=Frame(root)
textarea = Text(frama, height=20, width=40, background='white')
scroll = Scrollbar(frama, command=textarea.yview)
textarea.configure(yscrollcommand=scroll.set)
textarea.pack(side=LEFT)
scroll.pack(side=RIGHT, fill=Y)
frama.pack()

boton=Button(root, text="Pinchame")
boton.pack()

root.mainloop()

XD YO

 Eso era lo que ya había intentado... :-(

Pero cuando lo combino con mi código con la única modificación, claro, de cambiarle el nombre a la ventana raíz, me manda un error en la linea de comandos cuando lo ejecuto:
 
File "formulario.py", line 26, in <module>
    formulario.pack()
  File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1725, in __getattr__
    return getattr(self.tk, attr)
AttributeError: pack


Y cuando hago algo por modificar el error,y después la ejecuto desde la terminal, esta, se queda pasmada y sin aparecer la ventana

También, es que lo que yo realmente quisiera seria poder hacer el scrollbar sin necesidad alguna de tener que definir un textarea....

en resumen:
¿Sera por que yo los acomodo usando grid en lugar de pack?
¿Existe alguna manera de no tener que invocar un textarea para aparecer la scrollbar?
:-\ :o

De nuevo gracias...
"Fácilmente aceptamos la realidad, acaso porque intuimos que nada es real"
-Borges -El inmortal

43H4FH44H45H4CH49H56H45H

Este ejemplo de python 2.6 podria servirte "Demo/tkinter/matt/canvas-with-scrollbars.py"

Código (python) [Seleccionar]
from Tkinter import *
class Test(Frame):
   def printit(self):
       print "hi button"
   def createWidgets(self):
       self.question = Label(self, text="Can Find The BLUE Square??????")
       self.question.pack()
       self.QUIT = Button(self, text='Press', background='red',
                          height=3, command=self.printit)
       self.QUIT.pack(side=BOTTOM, fill=BOTH)
       spacer = Frame(self, height="0.25i")
       spacer.pack(side=BOTTOM)
       # notice that the scroll region (20" x 20") is larger than
       # displayed size of the widget (5" x 5")
       self.draw = Canvas(0, width="5i", height="5i",
                          background="white",
                          scrollregion=(0, 0, "20i", "20i"))
       self.draw.scrollX = Scrollbar(0, orient=HORIZONTAL)
       self.draw.scrollY = Scrollbar(0, orient=VERTICAL)
       # now tie the three together. This is standard boilerplate text
       self.draw['xscrollcommand'] = self.draw.scrollX.set
       self.draw['yscrollcommand'] = self.draw.scrollY.set
       self.draw.scrollX['command'] = self.draw.xview
       self.draw.scrollY['command'] = self.draw.yview
       # draw something. Note that the first square
       # is visible, but you need to scroll to see the second one.
       self.draw.create_rectangle(0, 0, "3.5i", "3.5i", fill="black")
       self.draw.create_rectangle("10i", "10i", "13.5i", "13.5i", fill="blue")
       # pack 'em up
       self.draw.scrollX.pack(side=BOTTOM, fill=X)
       self.draw.scrollY.pack(side=RIGHT, fill=Y)
       self.draw.pack(side=LEFT)
   def scrollCanvasX(self, *args):
           print "scrolling", args
           print self.draw.scrollX.get()
   def __init__(self, master=None):
           Frame.__init__(self, master)
           Pack.config(self)
           self.createWidgets()
test = Test()
test.mainloop()

-R IP
:0100
-A 100 
2826:0100 MOV AH,09
2826:0102 MOV DX,109
2826:0105 INT 21
2826:0105 MOV AH,08
2826:0105 INT 21
2826:0107 INT 20
2826:0109 DB 'MI NICK ES CODELIVE.$' 
2826:0127 
-R BX
:0000
-R CX
:20
-N CODELIVE.COM
-W

^Tifa^

AttributeError: pack

Estas usando un grid como widget padre y estas incluyendole ese Textarea con un pack????

CitarY cuando hago algo por modificar el error,y después la ejecuto desde la terminal, esta, se queda pasmada y sin aparecer la ventana

Lol si ese error me pasa bastante con Perl/Tk  :xD sobretodo cuando empaqueto un widget padre con pack() y a los widgets hijos los empaqueto con grid() o parte de los widgets hijos mezclados con pack() y grid()  :xD

No sale la ventana cuando lo ejecuto  :xD  (creo que es una funcionalidad del bindings Tk en estos lenguajes... o a lo mejor es una funcionalidad real del API Tk como tal) sea cual sea el caso, que me late bastante que este es tu problema (padre empaquetado con pack() hijo empaquetado con grid() ) O me equivoco???

No estaria mal sino logras resolver, que postees ese trozito de codigo donde defines widget padre y widget hijo con pack() y grid() mezclados  :D

XD YO

Si, es un problema que me trae loco  :rolleyes: :rolleyes:
43H4FH44H45H4CH49H56H45H, el problema es que no estoy trabajando con canvas aun
Y es que quiero tener la posibilidad de poder insertar un scrollbar a lado de todos mis widgets, ya que,  es que es una ventana enorme: :-[

si un pequeño monstruo de 400 lineas... ;)
Citar
Lol si ese error me pasa bastante con Perl/Tk  :xD sobretodo cuando empaqueto un widget padre con pack() y a los widgets hijos los empaqueto con grid() o parte de los widgets hijos mezclados con pack() y grid()  :xD

^TiFa^ , si te refieres a que la ventana padre tiene pack para acomodar sus widgets y la hija grid, eso nunca me dio problemas; pero cuando añado ese código a la ventana hija... es cuando comienza a ponerse quisquillosa y no sale :xD

"Fácilmente aceptamos la realidad, acaso porque intuimos que nada es real"
-Borges -El inmortal

^Tifa^

Me refiero por ejemplo... declaras un widget Frame con pack()   y dentro de ese mismo Frame declaras digamos 4 botones con grid() perfecto todo funciona. Pero si dentro de ese mismito Frame, agregas ademas de los botones digamos un Entry con pack().... cuando ejecutes la aplicacion No se mostrara la ventana aunque esta en ejecucion  :xD

Ya se te ha expuesto como insertar Scrollbars solo que debes llevar un orden, si declaras 1 widget hijo con grid() deberas declarar todos los widgets hijos dentro de esa misma ventana o frame con grid() no puedes remezclar pack() y grid()

XD YO

CitarMe refiero por ejemplo... declaras un widget Frame con pack()   y dentro de ese mismo Frame declaras digamos 4 botones con grid() perfecto todo funciona. Pero si dentro de ese mismito Frame, agregas ademas de los botones digamos un Entry con pack().... cuando ejecutes la aplicacion No se mostrara la ventana aunque esta en ejecucion  :xD

Si, lo intente y en vendad no se puede hacer eso  :xD

Y sobre el scrollbar

Si, ya logre  añadir el scrollbar a la ventana :D
Lo único malo es que no logro hacer que funcione  :-(

Pero supongo que a de ser por algún error que cometí al incluirlo, a si que decidí seguir intentando.
"Fácilmente aceptamos la realidad, acaso porque intuimos que nada es real"
-Borges -El inmortal

XD YO

#8
Bueno, ya me habia dado por vencido, cuando buscando como incluir dentro de un Canva elementos, me encontre con este precioso ejemplo en http://effbot.org/zone/editing-canvas-text-items.htm

Código (python) [Seleccionar]

from Tkinter import *

class AutoScrollbar(Scrollbar):
   # a scrollbar that hides itself if it's not needed.  only
   # works if you use the grid geometry manager.
   def set(self, lo, hi):
       if float(lo) <= 0.0 and float(hi) >= 1.0:
           # grid_remove is currently missing from Tkinter!
           self.tk.call("grid", "remove", self)
       else:
           self.grid()
       Scrollbar.set(self, lo, hi)
   def pack(self, **kw):
       raise TclError, "cannot use pack with this widget"
   def place(self, **kw):
       raise TclError, "cannot use place with this widget"

#
# create scrolled canvas

al = Tk()
al.columnconfigure(0,weight=1)
al.rowconfigure(0,weight=1)

header = Frame(al)
header.pack(side= TOP, expand = YES)

htxt = Label(header,text='TOP TOP TOP... this is the TOP')
htxt.pack()

footer = Frame(al)
footer.pack(side = BOTTOM, expand = YES)

ftxt = Label(footer,text='BOTTOM BOTTOM BOTTOM... this is the BOTTOM!')
ftxt.pack()
########
root = LabelFrame(al, bd=2, text='Data',relief='groove',padx=5, pady=5)
root.pack(side = TOP, expand = YES)

vscrollbar = AutoScrollbar(root)
vscrollbar.grid(row=0, column=1, sticky=N+S)
hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
hscrollbar.grid(row=1, column=0, sticky=E+W)

canvas = Canvas(root,
               yscrollcommand=vscrollbar.set,
               xscrollcommand=hscrollbar.set)
canvas.grid(row=0, column=0, sticky=N+S+E+W)

vscrollbar.config(command=canvas.yview)
hscrollbar.config(command=canvas.xview)

# make the canvas expandable
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

# create canvas contents

frame = Frame(canvas)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)

rows = 20
for i in range(1,rows):
   for j in range(1,20):
       button = Button(frame, padx=7, pady=7, text="[%d,%d]" % (i,j))
       button.grid(row=i, column=j, sticky='news')

canvas.create_window(0, 0, anchor=NW, window=frame)

frame.update_idletasks()

canvas.config(scrollregion=canvas.bbox("all"))

root.mainloop()


Todos los elementos estan perfectamente dentro de un labelframe, lo que lo hace bastante comodo, y lo que significa, que solo tengo que colocar los elementos con definicion en el interiro del labelframe, lo cual me parece muy bien  ;-)
"Fácilmente aceptamos la realidad, acaso porque intuimos que nada es real"
-Borges -El inmortal