2009-10-20 68 views
0

我需要實現一個移動列表框。唯一相關的控件是向上和向下箭頭鍵。列表框應顯示列表中的行數(screen_rows),其中一行應該是高亮的(sel_row),並且如果用戶在第一個項目高亮顯示時向上箭頭或向下箭頭如果最後一個項目被突出顯示(即,如果用戶在第一個項目突出顯示時彈起,則應顯示最後一個項目並突出顯示)。向上箭頭突出顯示前一個項目,向下箭頭突出顯示下一個項目。實現一個列表框

我把東西放在一起,但我擔心我錯過了測試中的東西。考慮到列表框的普及,必須有一個標準的方法來做到這一點。

def up_key(self): 
    if self.sel_row > 0: 
     self.sel_row -= 1 

    elif self.top_item > 0: # top_item is the index of the first list item 
     self.top_item -= 1 

    elif self.top_item == 0: 
     if self.n_lines >= self.screen_rows: # n_lines is the number of items in the list 
      self.top_item = self.n_lines - self.screen_rows 
      self.sel_row = min(self.screen_rows-1, self.n_lines-1) 
     else: 
      self.top_item = 0 
      self.sel_row = self.n_lines-1 


def down_key(self): 
    if self.sel_row < self.screen_rows-1 and self.sel_row < self.n_lines-1: 
     self.sel_row += 1 

    elif self.sel_row == self.screen_rows-1: 
     bottom_item = self.top_item + self.screen_rows 
     if bottom_item == self.n_lines: 
      self.top_item = 0 
      self.sel_row = 0 
     if bottom_item < self.n_lines: 
      self.top_item += 1 

    elif self.sel_row == self.n_lines-1: 
     self.top_item = 0 
     self.sel_row = 0 

def set_pos(self, pos): # display item with index pos 
    if pos < 0: 
     pos = 0 
    elif pos >= self.n_lines: 
     pos = self.n_lines - 1 

    if pos < self.screen_rows: 
     self.top_item = 0 
     self.sel_row = pos 
    else: 
     self.sel_row = min(self.screen_rows, self.n_lines)//2 - 1 
     self.top_item = pos - self.sel_row 
     if self.top_item >= self.n_lines - self.screen_rows: 
      self.top_item = self.n_lines - self.screen_rows - 1 
      self.sel_row = pos - self.top_item - 1 

編輯:每個功能後我所說的重繪屏幕功能,其重繪top_item屏幕的頂部和SEL-行突出顯示。

我已經添加了一個僞代碼標籤,以防某人在某些不是python的版本中有版本。

回答

1

很少有Python程序從頭開始實現列表框 - 它們通常只是從現有的工具包中獲取。這也許可以解釋爲什麼沒有真正的跨工具包「標準」 - - !)

來到你的代碼,我想象set_pos意味着後要正確或者叫做up_keydown_key是成品(你不要讓這個完全清楚)。

我的主要擔心是你的兩個例程之間的重複和不對稱。當然,鑑於你的規格對於上下鍵非常相似,你希望委託給一個單獨的函數,該函數需要一個「增量」參數,+1或-1。這種常見功能首先可以做self.sel_row += increment,然後在sel_row仍然正常的情況下立即返回,即if self.top_item <= self.sel_row < self.top_item + self.screen_rows;否則處理sel_row已退出當前顯示區域的情況,通過調整self.top_item,退出如果不需要環繞,或者最終處理環繞情況。

我一直渴望申請「扁平好於嵌套」,反覆使用形式的結構「做一些必要的狀態機會;如果事情現在好了,返回」而不是邏輯上更復雜「如果做一個簡單的事情會好的,然後做簡單的事情;否則,如果需要更復雜但不可怕的事情,那麼做一些複雜的事情;否則,如果我們處在一個非常複雜的情況下,處理這個非常複雜的問題。「 - 後者在任何情況下都更容易出錯並更難遵循。

+0

我曾經看到在gui編程的早年在c或C++中實現的列表框,但我找不到任何示例。無論如何,我會看看是否改變了你的建議,讓事情變得更簡單,並酌情返回 – foosion 2009-10-20 16:05:53

+0

@foosion,是的,在GUI框架和小部件出現之前,有合理的功能,當編程到裸露的xlib或一個人寫了一個自己的小工具 - 在那裏,做了那個,但是,一個* LONG *前一陣子!) – 2009-10-21 02:11:33

+0

@Alex,它只有20年左右的時間:-) – foosion 2009-10-21 11:15:11