Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使单个Tkinter Listbox元素以换行方式显示?_Python_String_User Interface_Tkinter_Listbox - Fatal编程技术网

Python 如何使单个Tkinter Listbox元素以换行方式显示?

Python 如何使单个Tkinter Listbox元素以换行方式显示?,python,string,user-interface,tkinter,listbox,Python,String,User Interface,Tkinter,Listbox,我有一个工作的Tkinter.Listbox对象,但我想设置它,使其元素可以有回车,而不必以某种方式设置多个链接项 例如,如果我想生成一个包含如下项目的选择窗格 # Here are four elements for the selector Listbox.. lb_items = ('mama', 'luigi', 'my birds', \ 'this is a single element\n spanning two lines!') # Th

我有一个工作的
Tkinter.Listbox
对象,但我想设置它,使其元素可以有回车,而不必以某种方式设置多个链接项

例如,如果我想生成一个包含如下项目的选择窗格

    # Here are four elements for the selector Listbox..
lb_items = ('mama', 'luigi', 'my birds', \
            'this is a single element\n spanning two lines!')
    # This generates and displays the selector window..
tk_selector = SingleSelect(lb_items, "TEST SELECTOR")
tk_selector.run_selector()
…如果我能让输出看起来像这个模型那就太好了

…而不是它实际产生的,这是

列表框似乎完全忽略了
'\n'
和带有行返回的三引号字符串;如果使用
\n
,则不会显示字符或换行符

是否可以有单独的、可选的列表框元素以换行符的形式出现?

我也会对换行选项感到满意,但在仔细查看之后,我通常在
Listbox
Tk
中找不到任何这样的选项


我可能会通过将多行字符串转换成多个元素,然后将其设置为在调用任何一个元素时返回整行来伪造效果,但是,对于可能有一个简单解决方案的东西来说,这感觉像是一场考验。

列表框项目不可能分布在多行或多行。

正如Bryan Oakley所说,
列表框
中没有对回车的本地支持,因此我尝试构建我在问题中提到的“假”版本,事实证明,这并不难

我的解决方案是在将每个“原始”字符串插入
列表框之前解析它们,使用
拆分行将字符串拆分为单独的行,记录行数以及列表框元素滚动中的哪些索引对应于哪个未中断的输入字符串,然后使用
Listbox.bind('',self.\u reselection\u fxn)
选择列表框的选择更改时选择所有部分

  • 下面有一个删节和注释的示例,或者您也可以

类多行单行选择器(对象):
##请选择一个比这个更好的类名:/
定义初始化(self,itemlist,…):
# ..
lb_splitlines=self._parse_字符串(itemlist)
#^拆分原始字符串并记录其索引。
#将拆分的字符串作为列表框元素的列表返回。
self.my_Listbox.insert(0,*lb_分割线)
#^将转换后的字符串放入列表框。。
self.my\u Listbox.bind(“”,self.\u重新选择)
#^无论何时修改列表框选择,都会触发
#事件。绑定\u重新选择以确定
#选择更新时应高亮显示哪些行。
# ..
定义解析字符串(自身、字符串列表):
''接受字符串列表并将每个字符串拆分为一系列行,
记录集合,并将它们存储在item_花名册和string_register属性中。
返回要插入列表框的拆分字符串。“”
self.index\u集=index\u集=[]
#^此列表中的每个元素都是包含第一个和最后一个元素的元组
#一组行的列表框元素索引。
self.string_register=寄存器={}
#^一个dict,其整个字符串元素被键入其
#列表框中的第一个元素。
所有_行=[]
#^每个列表框元素的列表。当一根绳子断成几行时,
#线在这里。
线号=0
对于字符串列表中的项目:
行=项。拆分行()
所有_行。扩展(行)#将分割的字符串添加到字符串堆栈中
寄存器[行号]=项目
#^保存此项目,并将其键入与其关联的第一个Listbox元素
#有。如果在列表框关闭时选择了该项目,则原始
#根据此索引编号找到并返回(整个)字符串。
数量=长度(行)
如果数量=1:#单行项目。。
索引集。追加((行号,行号))
其他:#此项目中有多行。。
元素范围=行号,行号+数量-1
#^列表框索引的范围。。
索引集扩展([元素范围]*数量)
#^..列表框中的每个元素一个。
行号+=数量#增加行号。
返回所有_行
def_重新选择(自身,事件=无):
“每当列表框的选择更改时调用。”
selection=self.my_Listbox.curselection()#获取新的选择数据。
如果未选择:#如果未选择任何内容,则不执行任何操作。
返回
行\u st,行\u ed=self.index\u集[选择[0]]
#^获取与当前选择关联的字符串块。
self.my\u Listbox.selection\u set(行,行)
#^选择与原始字符串关联的所有行。
def_召回(自身,事件=无):
“获取当前所选项目的完整字符串。”
selection=self.my_Listbox.curselection()
如果选择:#选择了一个项目!
返回self.string\u寄存器[选择[0]]
返回无#未选择任何项目。
如果您调整此代码以匹配您自己的代码,并将其放入现有的列表框设置中,它应该允许您模拟回车。它与本机换行或直接在
列表框中解析函数
\n
-不同,但它的作用基本相同

要获得与当前选择相对应的整个字符串,只需将
\u recall
绑定到您希望返回的任何输入或事件。在这种情况下,如果未选择任何项目,则返回
None

考虑到预期效果的复杂性,这也需要做大量的工作,但可能并不合适
class Multiline_Single_Selector(object):
      ## Go ahead and choose a better class name than this, too. :/
    def __init__(self, itemlist, ..):
              # ..
        lb_splitlines = self._parse_strings(itemlist) 
          # ^ splits the raw strings and records their indices.
          #  returns the split strings as a list of Listbox elements.
        self.my_Listbox.insert(0, *lb_splitlines) 
          # ^ put the converted strings into the Listbox..

        self.my_Listbox.bind('<<ListboxSelect>>', self._reselect)
          # ^ Whenever the Listbox selection is modifed, it triggers the
          #  <<ListboxSelect>> event. Bind _reselect to it to determine
          #  which lines ought to be highlighted when the selection updates.
              # ..

    def _parse_strings(self, string_list):
        '''Accepts a list of strings and breaks each string into a series of lines,
logs the sets, and stores them in the item_roster and string_register attributes.
Returns the split strings to be inserted into a Listbox.'''

        self.index_sets = index_sets = []
          # ^ Each element in this list is a tuple containing the first and last
          #  Listbox element indices for a set of lines. 

        self.string_register = register = {}
          # ^ A dict with a whole string element keyed to the index of the its
          #  first element in the Listbox.

        all_lines = [] 
          # ^ A list of every Listbox element. When a string is broken into lines,
          #  the lines go in here.

        line_number = 0
        for item in string_list: 
            lines = item.splitlines()

            all_lines.extend(lines) # add the divided string to the string stack
            register[line_number] = item
                # ^ Saves this item keyed to the first Listbox element it's associated
                #  with. If the item is selected when the Listbox closes, the original 
                #  (whole) string is found and returned based on this index number.

            qty = len(lines)
            if qty == 1: # single line item..
                index_sets.append((line_number, line_number))
            else: # multiple lines in this item..
                element_range = line_number, line_number + qty - 1 
                  # ^ the range of Listbox indices..
                index_sets.extend([element_range] * qty) 
                  # ^ ..one for each element in the Listbox.

            line_number += qty # increment the line number.
        return all_lines

    def _reselect(self, event=None):
        "Called whenever the Listbox's selection changes."
        selection = self.my_Listbox.curselection() # Get the new selection data.
        if not selection: # if there is nothing selected, do nothing.
            return

        lines_st, lines_ed = self.index_sets[selection[0]]
            # ^ Get the string block associated with the current selection.
        self.my_Listbox.selection_set(lines_st, lines_ed) 
            # ^ select all lines associated with the original string.

    def _recall(self, event=None):
        "Get the complete string for the currently selected item."
        selection = self.my_Listbox.curselection()
        if selection: # an item is selected!
            return self.string_register[selection[0]]
        return None   # no item is selected.