I have a function that updates listbox entries by removing and re-inserting them with an updated counter, however difficulty arises when I try to maintain a highlighted item, as it has been removed there is nothing to highlight.
My question is how can I get the program to remember what was highlighted?
Code:
#!/usr/bin/python
from time import clock, sleep
from os import system
from collections import defaultdict
from subprocess import PIPE, Popen
from threading import Thread, Lock
import Tkinter as tk
import Queue
import signal
import os, sys
# -------------------------------------------------------------------
# Global Definitions
mydict ={} # define the dictionary
dict_lock = Lock()
transList = []
running = 0
Counter = 0
edit_ref= 0
RecvQueue = Queue.Queue()
terminate = 0
pcanbus = "/dev/pcanusb0"
# ***************************************************************
#
# ************************ PCAM Msg ************************
#
# ***************************************************************
class PCANmsg(object):
def __init__(self):
self.dlc = 0
self.CANtime = 0
self.PCANperiod = 0
self.COUNT = 0
self.hdata0 = 0
self.hdata1 = 0
self.hdata2 = 0
self.hdata3 = 0
self.hdata4 = 0
self.hdata5 = 0
self.hdata6 = 0
self.hdata7 = 0
self.timing = 0
class ThreadedTask(Thread):
def __init__(self, queue):
Thread.__init__(self)
self.queue = queue
def run(self):
global proc
payload = iter(proc.stdout.readline, "")
for line in payload:
if line[0].isdigit():
splitline = line.split()
self.dictAdd(splitline)
def dictAdd(self, info):
global mydict
try:
can_ID = info[4]
p = PCANmsg()
p.dlc = int(info[5])
p.CANtime = float(info[0])
p.hdata0 = info[6]
p.hdata1 = info[7]
p.hdata2 = info[8]
p.hdata3 = info[9]
p.hdata4 = info[10]
p.hdata5 = info[11]
p.hdata6 = info[12]
p.hdata7 = info[13]
p.timing = 1
if can_ID in mydict.keys():
q = mydict[can_ID]
p.COUNT = q.COUNT + 1
p.PCANperiod = p.CANtime - q.CANtime
else:
p.COUNT = 1
p.PCANperiod = 0.0
mydict[can_ID] = p
s = '%06X : %3d %02X %02X %02X %02X %02X %02X %02X %02X\t %8.2F %8d ' %\
(int(can_ID,16),
p.dlc,
int(p.hdata0, 16),
int(p.hdata1, 16),
int(p.hdata2, 16),
int(p.hdata3, 16),
int(p.hdata4, 16),
int(p.hdata5, 16),
int(p.hdata6, 16),
int(p.hdata7, 16),
p.PCANperiod,
p.COUNT)
self.queue.put(s)
except IndexError:
pass
# ***************************************************************
#
# ************************ RecvTran GUI *************************
#
# ***************************************************************
class application:
def __init__(self,window):
self.window = window
self.window.title("PYCAN")
"""Initialize the Application """
window.grid_rowconfigure(9,weight=1)
self.RecvButton = tk.Button(window,
text = "Receive",
command = self.RecvBtn_Click)
self.RecvButton.grid(row = 9, column = 12)
self.TransLabel = tk.Label(window, text = "Messages Received:")
self.TransLabel.grid(row = 8, columnspan = 2)
self.RecvList = tk.Listbox(window, height = 10, width = 60, exportselection=False)
self.RecScrol = tk.Scrollbar(window)
self.RecScrol.grid(row=9, column=11, sticky=tk.NW+tk.SE)
self.RecvList.grid(row = 9, rowspan = 3, columnspan = 11, sticky=tk.NW+tk.SE)
self.RecScrol.config(command=self.RecvList.yview)
self.RecvList.config(yscrollcommand=self.RecScrol.set)
self.RecvList.bind("<Button-1>", self.KeepSelection)
self.QuitButton = tk.Button(window,
text = 'Exit',
command = QuitBtn_Click)
self.QuitButton.grid(row = 14, column = 12)
window.protocol("WM_DELETE_WINDOW", QuitBtn_Click)
def KeepSelection(self, event):
lb = event.widget
selection = lb.curselection()
value = lb.get(selection[0])
print "%s" % value
selected = int(value)
self.lb.select_set(selected)
def RecvBtn_Click(self, event=None):
global RecvQueue, Counter
try:
info = RecvQueue.get(0)
info_split = info.split()
if self.RecvList.size() < len(mydict):
#for _i in mydict.keys():
for _i in sorted(mydict.keys()):
self.RecvList.insert("end",'%06X : %3d %02X %02X %02X %02X %02X %02X %02X %02X %8.1F %8d ' %\
(int(_i,16),
mydict[_i].dlc,
int(mydict[_i].hdata0, 16),
int(mydict[_i].hdata1, 16),
int(mydict[_i].hdata2, 16),
int(mydict[_i].hdata3, 16),
int(mydict[_i].hdata4, 16),
int(mydict[_i].hdata5, 16),
int(mydict[_i].hdata6, 16),
int(mydict[_i].hdata7, 16),
mydict[_i].PCANperiod,
mydict[_i].COUNT))
else:
for i, listbox_entry in enumerate(self.RecvList.get(0, "end")):
list_split = listbox_entry.split()
if list_split[0] == info_split[0]:
pos = self.RecScrol.get()
self.RecvList.delete(i)
self.RecvList.insert(i, info)
self.RecvList.yview_moveto(pos[0])
else:
continue
# self.RecvList.insert("end", info)
self.window.after(20, self.RecvBtn_Click)
Counter += 1
if Counter > 25:
with RecvQueue.mutex:
RecvQueue.queue.clear()
Counter = 0
except Queue.Empty:
self.window.after(50, self.RecvBtn_Click)
def QuitBtn_Click(event=None):
global terminate
global proc
terminate = 1
try:
if terminate == 1:
os.kill(proc.pid, 0)
proc.kill()
root.destroy()
except OSError, e:
print "terminated Gracefully"
# ***************************************************************
#
# ************************ Script Start ************************
#
# ***************************************************************
if __name__ == "__main__":
try:
proc = Popen(("receivetest -f=%s" % pcanbus).split(), stdout = PIPE)
except OSError:
print "ERROR ESTABLISHING CONNECTION"
DataStream = ThreadedTask(RecvQueue)
DataStream.daemon = True
DataStream.start()
root = tk.Tk()
myapp = application(root)
root.mainloop()
# --------------------------------------------------------------
Hoepfully you can see what I am trying to do. My Selection method doesn't work because the index is removed and thus has nothing to map to.
Data that would be expected:
12106694.169 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12106694.638 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12106695.107 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12106695.577 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12106794.137 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12106794.649 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12106795.118 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12106795.587 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12106894.147 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12106894.617 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12106895.86 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12106895.598 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12106994.158 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12106994.627 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12106995.97 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12106995.566 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12107094.169 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12107094.638 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12107095.107 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12107095.619 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12107194.179 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12107194.649 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12107195.118 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12107195.587 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12107294.147 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12107294.659 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12107295.129 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12107295.598 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12107394.158 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12107394.627 receivetest: m s 0x0000069e 8 00 1f be 0f ea 0a 58 1a
12107395.97 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
12107395.566 receivetest: m s 0x00000690 8 00 20 06 0f ea 0a 58 1a
12107494.254 receivetest: m s 0x0000069a 8 00 00 00 00 00 0a 58 1a
12107494.766 receivetest: m s 0x00000690 8 00 20 06 00 00 0a 58 1a
12107495.235 receivetest: m s 0x00000691 8 01 1e 6e 4b 50 5a 06 00
12107495.662 receivetest: m s 0x00000663 8 2f 00 62 02 00 0a 58 1a
All you have to do is get the index of the highlighted items, replace the data, and then re-select the highlighted items. If each item is unique, the process is extremely simple.
If the items are not unique, it's still possible. All you need to do is save the index of each selected item. When you delete something, remember the index of the item that was deleted. When restoring the selection, the indexes for items above the deleted item will be unchanged, and the indexes for the items below the one that was deleted need to subtract one (ie: if you delete item #5 and #10 was selected, after the delete you need to re-select #9)
Here is the solution for when you know the items in the listbox are unique.
First, this saves everything that was selected, by value:
def saveSelection(lb):
selection = []
for i in lb.curselection():
selection.append(lb.get(i))
return selection
Later, you can restore the selected items with this:
def restoreSelection(lb, selectedItems):
lb.selection_clear(0, "end")
items = lb.get(0, "end")
for item in selectedItems:
if item in items:
index = items.index(item)
lb.selection_set(index)
User contributions licensed under CC BY-SA 3.0