-1

There are 2 threads. One is providing the number, the other is the one using tkinter that catches the number once it is produced.

I use scrollbar for the number sequences. However, i want to see some details of what i click, like the square number.

For example, if i click 8 in Result,i can get 64 in Detail

picture of my idea

So how to achieve this? My current code is here:

from concurrent.futures import ThreadPoolExecutor
from tkinter import *
from time import sleep
global root
global scrollbar
global listb

def my_func1():
    global root
    global Scrollbar
    root = Tk()
    lbl1 = Label(root, text="Result:", fg='black',
                 font=("Helvetica", 16, "bold"))
    lbl2 = Label(root, text="Detail:", fg='black',
                 font=("Helvetica", 16, "bold"))
    lbl1.grid(row=0, column=0,  sticky=W)
    lbl2.grid(row=2, column=0,  sticky=W)

    frm = Frame(root)
    frm.grid(row=1, columnspan=2, sticky=N + S + W + E)

    try:
        scrollbar = Scrollbar(frm, orient=VERTICAL)
        global listb
        listb = Listbox(frm, yscrollcommand=scrollbar.set, width=50)
        scrollbar.config(command=listb.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        listb.pack(fill=BOTH, expand=YES)
        detail = Listbox(root, height=10, font=("Helvetica", 12))
        detail.grid(row=6, columnspan=2, sticky=E + W + N)
    except:
        pass
    root.mainloop()

def my_func2():
    global listb
    sleep(0.1)
    for i in range(1000):
        sleep(0.3)
        vw = listb.yview()
        listb.insert(END, i)
        listb.yview_moveto(vw[-1])
        print(i)
executors_list = []

with ThreadPoolExecutor(max_workers=5) as executor:
    executors_list.append(executor.submit(my_func1))
    executors_list.append(executor.submit(my_func2))
furas
  • 134,197
  • 12
  • 106
  • 148
user6456568
  • 579
  • 9
  • 23
  • 1
    [Getting a callback when a Tkinter Listbox selection is changed?](https://stackoverflow.com/questions/6554805/getting-a-callback-when-a-tkinter-listbox-selection-is-changed) – furas Nov 21 '17 at 09:32
  • @furas Yes I want to achieve that. I don't why it doesn't work when I use 'bind'. – user6456568 Nov 21 '17 at 09:36
  • Have you tried the second answer of the question linked by furas? – j_4321 Nov 21 '17 at 09:43
  • 1
    1) Your code isn't thread safe (for e.g. a `Tcl_AsyncDelete` exception on quit), so I suggest to rewrite it first ([some suggestions](https://stackoverflow.com/a/26703844/6634373)). 2) For actual question - listbox rises the [`'<>'` event](http://www.tcl.tk/man/tcl8.7/TkCmd/event.htm#M41), so you able to handle this easily, when you done with first point. – CommonSense Nov 21 '17 at 09:45
  • Possible duplicate of [Getting a callback when a Tkinter Listbox selection is changed?](https://stackoverflow.com/questions/6554805/getting-a-callback-when-a-tkinter-listbox-selection-is-changed) – CommonSense Nov 21 '17 at 09:47
  • @CommonSense Thanks a lot, it finally works. By the way, I want to know whether it's possible when I select the item the scollbar position will be locked? – user6456568 Nov 21 '17 at 10:28
  • @user6456568, sure it possible. Main idea - suppress `yview_moveto` execution in your threaded function, while something is selected. It's easy to implement, since you got full control over listbox. But it's really an another question! – CommonSense Nov 21 '17 at 10:41

1 Answers1

1

Thanks everyone for the help. The answer is here:

import time, threading
from time import sleep
from tkinter import *
from tkinter import messagebox
global listb

class App(object):
    def __init__(self, root):
        def onselect(evt):
            w = evt.widget
            index = int(w.curselection()[0])
            value = w.get(index)
            detail.delete('1.0', END)
            detail.insert(END,str(value*value))
        lbl1 = Label(root, text="Result:", fg='black',
                    font=("Helvetica", 16, "bold"))
        lbl2 = Label(root, text="Detail:", fg='black',
                        font=("Helvetica", 16, "bold"))
        lbl1.grid(row=0, column=0,  sticky=W)
        lbl2.grid(row=2, column=0,  sticky=W)

        frm = Frame(root)
        frm.grid(row=1, columnspan=2, sticky=N + S + W + E)


        scrollbar = Scrollbar(frm, orient=VERTICAL)
        global listb
        listb = Listbox(frm, yscrollcommand=scrollbar.set, width=50)
        scrollbar.config(command=listb.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        listb.pack(fill=BOTH, expand=YES)

        detail = Text(root, height=10, font=("Helvetica", 12))
        detail.grid(row=6, columnspan=2, sticky=E + W + N)
        listb.bind('<<ListboxSelect>>', onselect)


def InfiniteProcess():
    global listb
    sleep(0.1)
    for i in range(1000):
        sleep(0.3)
        vw = listb.yview()
        listb.insert(END, i)
        listb.yview_moveto(vw[-1])
        #print(i)

finish = False
Process = threading.Thread(target=InfiniteProcess)
Process.start()

mainWindow = Tk()
app = App(mainWindow)
mainWindow.mainloop()
finish = True
Process.join()
user6456568
  • 579
  • 9
  • 23