2009-10-20 73 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