【问题标题】:Make an editable table in PySimpleGUI?在 PySimpleGUI 中制作一个可编辑的表格?
【发布时间】:2021-12-30 04:21:33
【问题描述】:

您好,我正在使用 PySimpleGUI 中的 Table 元素。我希望用户能够编辑其中的数据。

我看到有人提到it。可能吗?这个人在使用 PySimpleGUIQt,而我在 tkinter 上使用 PySimpleGUI。

【问题讨论】:

    标签: python user-interface pysimplegui


    【解决方案1】:

    我很难用纯 PySimpleGUI 代码来构建它。 如果使用从 sg.Table 继承的新类,则不需要一些变量作为参数或全局变量。 此处,条目中未考虑单元格的颜色。

    以下示例的函数 edit_cell 中的所有 tkinter 代码。

    import PySimpleGUI as sg
    import random, string
    
    # ------ Some functions to help generate data for the table ------
    def word():
        return ''.join(random.choice(string.ascii_lowercase) for i in range(10))
    def number(max_val=1000):
        return random.randint(0, max_val)
    
    def make_table(num_rows, num_cols):
        data = [[j for j in range(num_cols)] for i in range(num_rows)]
        data[0] = [word() for _ in range(num_cols)]
        for i in range(0, num_rows):
            data[i] = [i, word(), *[number() for i in range(num_cols - 1)]]
        return data
    
    def edit_cell(window, key, row, col, justify='left'):
    
        global textvariable, edit
    
        def callback(event, row, col, text, key):
            global edit
            widget = event.widget
            if key == 'Return':
                text = widget.get()
                print(text)
            widget.destroy()
            widget.master.destroy()
            values = list(table.item(row, 'values'))
            values[col] = text
            table.item(row, values=values)
            edit = False
    
        if edit or row <= 0:
            return
    
        edit = True
        root = window.TKroot
        table = window[key].Widget
    
        text = table.item(row, "values")[col]
        x, y, width, height = table.bbox(row, col)
    
        frame = sg.tk.Frame(root)
        frame.place(x=x, y=y, anchor="nw", width=width, height=height)
        textvariable = sg.tk.StringVar()
        textvariable.set(text)
        entry = sg.tk.Entry(frame, textvariable=textvariable, justify=justify)
        entry.pack()
        entry.select_range(0, sg.tk.END)
        entry.icursor(sg.tk.END)
        entry.focus_force()
        entry.bind("<Return>", lambda e, r=row, c=col, t=text, k='Return':callback(e, r, c, t, k))
        entry.bind("<Escape>", lambda e, r=row, c=col, t=text, k='Escape':callback(e, r, c, t, k))
    
    def main_example1():
        global edit
    
        edit = False
        # ------ Make the Table Data ------
        # sg.Print('Creating table...')
        data = make_table(num_rows=1_000, num_cols=6)
        # headings = [str(data[0][x])+'     ..' for x in range(len(data[0]))]
        headings = [f'Col {col}' for col in range(len(data[0]))]
        # sg.Print('Done creating table.  Creating GUI...')
        sg.set_options(dpi_awareness=True)
        layout = [[sg.Table(values=data, headings=headings, max_col_width=25,
                            auto_size_columns=True,
                            # display_row_numbers=True,
                            justification='right',
                            num_rows=20,
                            alternating_row_color=sg.theme_button_color()[1],
                            key='-TABLE-',
                            # selected_row_colors='red on yellow',
                            # enable_events=True,
                            # select_mode=sg.TABLE_SELECT_MODE_BROWSE,
                            expand_x=True,
                            expand_y=True,
                            enable_click_events=True,  # Comment out to not enable header and other clicks
                            )],
                  [sg.Button('Read'), sg.Button('Double'), sg.Button('Change Colors')],
                  [sg.Text('Cell clicked:'), sg.T(k='-CLICKED-')]]
    
    
        window = sg.Window('Table Element - Example 1', layout, resizable=True, finalize=True)
    
        while True:
            event, values = window.read()
            if event in (sg.WIN_CLOSED, 'Exit'):
                break
            elif isinstance(event, tuple):
                cell = row, col = event[2]
                window['-CLICKED-'].update(cell)
                edit_cell(window, '-TABLE-', row+1, col, justify='right')
    
        window.close()
    
    main_example1()
    

    【讨论】:

      【解决方案2】:

      我强烈建议使用 MutiLine 来显示表格,它更易于管理,并且可以轻松更新等。相同的表格效果可以通过更少的代码行来实现。在这里从我自己的数据库程序中给出一个示例代码,使用 Sqlite3 表。

      def ViewTable (TableNme):
      try: # LOAD TABLE FROM Sqlite3 Database
          txt2="SELECT * FROM {} ".format(TableNme)
          cursor.execute(txt2)
          ##Include headers###
          txt2='S.No '
          for j in fields: txt2=txt2+j +" "
          txt2=txt2+'\n'
          
          #converts the table into string separated by Comma
                 #fine as long as table is not very massive running more than 3 Mbs, having more than 1000 records
          while True:
                  h1=cursor.fetchone()
                  if not h1: break
                  for j in h1:txt2=txt2+str(j)+"   "
                  txt2=txt2+'\n'
          #sg.popup('Archieved table', txt2)
          #Define text to load by text= before calling me
          layout2 = [[sg.Multiline(txt2,size=(28,28),key='-Items-'),],[sg.Ok()] ]
          sg.Window('Scroll to see the whole database', layout2,finalize=True).read(close=True)
          
      except:
              sg.popup_error('Failed','Access denied or Memory full.')    
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-15
        • 1970-01-01
        • 1970-01-01
        • 2015-11-06
        • 1970-01-01
        • 2020-02-28
        • 1970-01-01
        相关资源
        最近更新 更多