2015-05-22 75 views
-1

我有一個通過刪除並重新插入更新的計數器來更新列表框項目的功能,但是當我嘗試維護突出顯示的項目時出現困難,因爲它已被刪除沒什麼可以突出的通過重寫保留選定的列表框項目

我的問題是如何讓程序記住突出顯示的內容?

代碼:

#!/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你可以看到什麼,我試圖做的。我的選擇方法不起作用,因爲索引被刪除,因此沒有任何東西可以映射到。

數據可以預期:

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 

編輯創建凝聚的代碼工作版本

+0

請,創建工作示例,這意味着例如,我們可以直接複製並運行並可視化您的情況。 – nbro

+0

@Xenomorph我編輯了工作示例的問題 – Jim

+0

好吧,即使它非常複雜......而且,當您使用線程時,每個程序都會變得複雜......我不確定我是否能夠提供幫助,但是我希望有人形象化的情況可以幫助你;) – nbro

回答

1

所有你需要做的就是得到突出顯示的項目的索引,替換數據,然後重新選擇突出顯示的項目。如果每個項目都是唯一的,那麼這個過程非常簡單。

如果項目不是唯一的,它仍然是可能的。您只需保存每個選定項目的索引。刪除某些內容時,請記住已刪除的項目的索引。恢復選擇時,刪除項目上方項目的索引將保持不變,並且刪除項目下方項目的索引需要減去1(即:如果刪除項目#5和#10,則選擇刪除你需要重新選擇#9)

下面是當你知道列表框中的項目是唯一的解決方案。

首先,這節省了所選擇的一切,按值:

def saveSelection(lb): 
    selection = [] 
    for i in lb.curselection(): 
     selection.append(lb.get(i)) 
    return selection 

以後,你可以用這個恢復選定的項目:

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) 
+0

嗨,我認爲這是正確的答案,但我努力將其納入我的程序,其中/我應該如何調用這些函數。任何建議將非常感謝 - 吉姆 – Jim

+0

@Jim:在改變列表框之前立即調用'saveSelection',改變它後立即調用'restoreSelection'。 –

+0

對不起,這個問題一直困擾着我,我嘗試過添加這個,但是對於我的生活無法完成它的工作,我想這是因爲當我刪除並重新插入該行時,它會將計數器增加1 '如果項目中的項目不是'真',我將如何僅基於該行的前6個字符來完成此操作,因爲它們是標識符,並且不會更改 – Jim