Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
295 views
in Technique[技术] by (71.8m points)

python - Tkinter, custom widget and label updates

Description

I want to make a custom "Table Widget" for Tkinter and so far it's almost as I want.

The problem I have is that I want the table to consist of "Labels", I have only found that you have to use "StringVar()'s" in order to update the labels.

I dont really want 1000 variables for 1000 labels so I have tried to solve this issue for a week now. The only solution I've found is to use "Dicts" but I dont think this is a good way to do it? I might be wrong but it feels like it has to be a way to do something like this:

myLabel = Label(root, text='myText')
myLabel.pack()
myLabel.setText('new text')

The current widget code looks like this (This is my first custom widget so if this is horribly wrong or wrong in any way, please tell me)

Source

"""
Description:
        A TABLE WIDGET Extension for Tkinter
"""
try:
    #Python 3.X
    import tkinter #this is quite annoyng, without it (tkinter) wont be available....
    from tkinter import * # even with this
    from tkinter import ttk
    from tkinter.ttk import *

except ImportError:
    #python 2.X
    import tkinter
    from Tkinter import *
    from Tkinter import ttk
    from Tkinter.ttk import *



class ETable(tkinter.Frame):
    def __init__(self, parent, *args, **kwargs):
        tkinter.Frame.__init__(self, parent)
        self.init_table(parent, *args, **kwargs)

    def init_table(self, parent, *args, **kwargs):
        row_settings = {
                           'anchor': CENTER,
                           'background': '#C5FFFF',
                           'bitmap': None,
                           'borderwidth': 5,
                           'compound': None,
                           'cursor': None,
                           'font': None,
                           'foreground': '#000000',
                           'image': None,
                           'relief': FLAT,
                           'rows': 1,
                           'state': NORMAL,
                           'text': None,
                           'textvariable': None,
                           'underline': -1,
                           'width': 20,
                        }

        for kwarg in kwargs:
            if kwarg in row_settings:
                row_settings[kwarg] = kwargs[kwarg]

        self.table_rows = self.init_row(parent, *args, **row_settings)

    def init_row(self, parent, *args, **kwargs):
        text_list = kwargs.pop('text')
        row_list = []

        cols = []
        rows = kwargs.pop('rows')


        for row in range(rows):
            for col in range(len(text_list)):
                tempLabel = Label(parent, text = text_list[col], *args, **kwargs)
                tempLabel.grid(row=row, column=col)
                cols.append(tempLabel)

            row_list.append(cols)
        return row_list

Goal

I want to be able to do something like this

table.getRow[0][0].setText('new text') #This would change col 1 in row 1 to "new text"

Bonus Question

(please tell me if I should make a new question for this)

As I said, I want to make a "Table Widget" for Tkinter but I also want to add behaviours to the table, IE when a user clicks on a row, I want the row to expand "Downwards" much like a "Dropdown Menu" but it will only close when it looses focus, the goal here is to add "Entry or Text boxes" in order to edit the columns.

The Question here is, is this possible with Tkinter?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I have only found that you have to use "StringVar()'s" in order to update the labels.

This is not a true statement. You can update the attributes of any widget with the config / configure method. Starting with your first example, it would look like this:

myLabel = Label(root, text='myText')
myLabel.pack()
myLabel.configure(text='new text')

And, in your final example:

table.getRow[0][0].configure(text='new text') 

As for the bonus question, yes, it's possible.You can bind any code you want to a label just as you can any other widget, and in addition to bindings on keys and mouse buttons, you can bind on gaining and losing focus.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...