0

I am trying to make a simple application launcher using Tkinter ( for the games that I have made using pygame). The code for the same is below.It runs in full screen mode(without any maximize or minimize buttons).

import Tkinter as tk
from Tkinter import *
import random
import os
import subprocess


def call(event,x):

   print "begin"
   if x==0:
       p = subprocess.Popen("python C:\Users\Akshay\Desktop\i.py")


   p.wait()
   print "end"



root = tk.Tk()
root.geometry("1368x768+30+30")
root.overrideredirect(True)
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(),    root.winfo_screenheight()))

games = ['Game1','Game2','Game3','Game4','Game5','Game6','Game7','Game8']
labels = range(8)
for i in range(8):
    ct = [random.randrange(256) for x in range(3)]
    brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))
    ct_hex = "%02x%02x%02x" % tuple(ct)
    bg_colour = '#' + "".join(ct_hex)
    l = tk.Label(root, 
            text=games[i], 
            fg='White' if brightness < 120 else 'Black', 
            bg=bg_colour)
    l.place(x = 320, y = 30 + i*150, width=700, height=100)
    l.bind('<Button-1>', lambda event, arg=i: call(event, arg))

root.mainloop()

There is no issue with this piece of code but I want a scroll bar at the right side or a way to scroll/move down using the arrow keys so that if I add more number of labels , they also become visible.

I tried to understand some code snippets from the internet and read the Tkinter documentations as well but didn't understood anything. Also tried to follow one more stackoverflow discussion and understood about the frame and canvas methods.

Python Tkinter scrollbar for frame

Frame , canvas and all is getting a bit complicated. I just want to keep it simple.Can something be added to the code snippet above to make the scroll thing work and all the labels become visible?

enter image description here

Something like the above but with a scroll bar!!

Community
  • 1
  • 1
Akshay
  • 463
  • 6
  • 15
  • The answer you linked to is the standard way to do this, though that exact implementation is a little clunky. – Bryan Oakley Apr 30 '15 at 18:02
  • Do you suggest me to play around with the above piece of code and make some alterations in it to make the scroll thing work or shall I try to implement what I want to do by tinkering around with the other piece of code(i.e the one in the link) – Akshay Apr 30 '15 at 18:23
  • I tried to do that even but am unable to use the l.place thing there.And when I am trying to define width and height there to a label widget then it is taking some very large values and showing some behaviour which I am unable to understand.Moreover the scrollbar sticks to the interior which I don't want.Is there any way to make it move down/scroll without a scrollbar being there(i.e by simply using arrow keys and navigating through the labels). – Akshay Apr 30 '15 at 18:26
  • place is irrelevant. That is only how that solution puts the scrolled frame into something else. You can use whatever you want. The point is, you create a canvas, add a frame to the canvas, and then hook up a couple of bindings. Here's another example: http://stackoverflow.com/a/3092341/7432 – Bryan Oakley Apr 30 '15 at 18:36
  • Oh! by this example things are pretty clear to me.I wish someone could give more insight into the syntax that what's exactly happening there.Then I think I can make what I want to though it appears a little complex.Otherwise it will take a large amount of time to understand Tkinter from complete basic.I am familiar with tkinter for just an hour or so.Anyways thanks for help. :-) – Akshay Apr 30 '15 at 18:42
  • Oh man! You are a genius at Tkinter. I went through your profile and a few blogs.Please help me out with this code sir! – Akshay Apr 30 '15 at 18:48

2 Answers2

1

Here is an MCVE of how to add a scrollbar to a tkinter app, hide the scrollbar, and scroll with the up/down arrows or the mouse wheel.

from tkinter import *

parent=Tk() # parent object
canvas = Canvas(parent, height=200) # a canvas in the parent object
frame = Frame(canvas) # a frame in the canvas
# a scrollbar in the parent
scrollbar = Scrollbar(parent, orient="vertical", command=canvas.yview)
# connect the canvas to the scrollbar
canvas.configure(yscrollcommand=scrollbar.set)
scrollbar.pack(side="right", fill="y") # comment out this line to hide the scrollbar
canvas.pack(side="left", fill="both", expand=True) # pack the canvas
# make the frame a window in the canvas
canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")
# bind the frame to the scrollbar
frame.bind("<Configure>", lambda x: canvas.configure(scrollregion=canvas.bbox("all")))
parent.bind("<Down>", lambda x: canvas.yview_scroll(3, 'units')) # bind "Down" to scroll down
parent.bind("<Up>", lambda x: canvas.yview_scroll(-3, 'units')) # bind "Up" to scroll up
# bind the mousewheel to scroll up/down
parent.bind("<MouseWheel>", lambda x: canvas.yview_scroll(int(-1*(x.delta/40)), "units"))
labels = [Label(frame, text=str(i)) for i in range(20)] # make some Labels
for l in labels: l.pack() # pack them

parent.mainloop() # run program
Community
  • 1
  • 1
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
-1

This is a better answer to my question.Yes I know I can't make the scroll bars work properly but yes as I asked now through this code one can move down/scroll via arrow keys without a scroll bar actually being there. This is the way I used to make menu for my pygame made games and the same technique I applied here.It works but only in fullscreen mode.

import Tkinter as tk
from Tkinter import *
import random
import os
import subprocess

class stat:
   j=0

def call(event,x):

   print "begin"
   if x==0:
       p = subprocess.Popen("python C:\Users\Akshay\Desktop\i.py")


   p.wait()
   print "end"

def OnEntryDown(event):
    stat.j=stat.j+1
    print stat.j
    xmain()

def OnEntryUp(event):

     stat.j=stat.j-1
     print stat.j
     xmain()
def xmain():   
     root = tk.Tk()
     root.geometry("1368x768+30+30")
     root.overrideredirect(True)
     root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(),       root.winfo_screenheight()))
     root.bind("<Down>", OnEntryDown)
     root.bind("<Up>", OnEntryUp)


     languages =     ['Game1','Game2','Game3','Game4','Game5','Game6','Game7','Game8']
 labels = range(8)

     k=0
     print stat.j
     for i in range(stat.j,stat.j+5):
        ct = [random.randrange(256) for x in range(3)]
        brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))
        ct_hex = "%02x%02x%02x" % tuple(ct)
        bg_colour = '#' + "".join(ct_hex)
        l = tk.Label(root, 
            text=languages[i], 
            fg='White' if brightness < 120 else 'Black', 
            bg=bg_colour)
        l.place(x = 320, y = 30 + k*150, width=700, height=100)
        l.bind('<Button-1>', lambda event, arg=stat.j: call(event, arg))
        k=k+1

     root.mainloop()

xmain()
Akshay
  • 463
  • 6
  • 15
  • 1
    I wouldn't recommend repeatedly recreating the root `Tk()` object. – TigerhawkT3 Apr 30 '15 at 20:30
  • Yes I modified that in my code. Recreating the root Tk() object is a bad idea! Instead of calling xmain() again and again what I did is put the rendering part(after the for loop till k=k+1) inside another function and call that function again and again(i.e whenever arrow keys are pressed).So that makes the code better! – Akshay Apr 30 '15 at 21:05