MCV tkinter和DB连接。意外的行为

时间:2017-10-31 17:55:31

标签: python mysql tkinter frames

我正在遵循Bryan在“在tkinter中切换两帧之间”的答案所做的MVC模型。他将框架堆叠在一起(所有框架都是在最开始制作)然后我们只是按照遗嘱展示它们。

我有两个简单的数据库表。第一个名为example_ini,有两列:lin_id和lin_option。表(1,2)中只有1个条目,它用于记住用户的最后一个选择,第二个是带有两列的example_options:lin_id和symbol。有4个条目(1,AA)(2,BB)(3,CC)和(4,DD)。我使用mysql,但我不认为这与问题有关。

只需打开和关闭代码即可更改数据库中的值。它看起来像是在页面制作时它在on_click中执行循环,而不应该。我怎么能阻止这种行为?

import tkinter as tk                # python 3
from tkinter import font  as tkfont # python 3
#import Tkinter as tk     # python 2
#import tkFont as tkfont  # python 2
from datetime import *
import mysql.connector

global __TBL_PREFIX__
__TBL_PREFIX__ = 'example_'

global config
config = {
    'db' : 'example',
    'user' : 'root',
    'password' : '****', # Your password
}

class ini:

    def __init__(self):
        self.lin_id = None
        self.lin_option = 0

    # return an object populated based on the record's lin id
    def getById(lin_id):
        i = ini()
        cnx = mysql.connector.connect(**config)
        cursor = cnx.cursor()
        query = ("SELECT LIN_OPTION FROM %sINI WHERE LIN_ID = %d")
        args = (__TBL_PREFIX__, lin_id)        
        query = query % args
        cursor.execute(query)
        results = cursor.fetchall()
        cnx.commit()
        if len(results) != 0 :
            i.lin_option = results[0][0]
            i.lin_id = lin_id
        cursor.close()
        cnx.close()
        return i

    # update an object in db
    def update(i):
        cnx = mysql.connector.connect(**config)
        cursor = cnx.cursor()   
        query = ('UPDATE %sINI SET LIN_OPTION = %d WHERE LIN_ID = %d')
        args = (__TBL_PREFIX__, i.lin_option, i.lin_id)
        query = query % args
        cursor.execute (query)
        cnx.commit()
        cursor.close()
        cnx.close()
        return 

class options:

    def __init__(self):
        self.lin_id = None
        self.symbol = ''

    # return an object populated based on the record's lin id
    def getById(lin_id):
        o = options()
        cnx = mysql.connector.connect(**config)
        cursor = cnx.cursor()
        query = ("SELECT SYMBOL FROM %sOPTIONS WHERE LIN_ID = %d")
        args = (__TBL_PREFIX__, lin_id)        
        query = query % args
        cursor.execute(query)
        results = cursor.fetchall()
        cnx.commit()
        if len(results) != 0 :
            o.symbol = results[0][0]
            o.lin_id = lin_id
        cursor.close()
        cnx.close()
        return o

    # return all candidates
    def getall():
        cnx = mysql.connector.connect(**config)
        cursor = cnx.cursor()
        query = ("SELECT LIN_ID FROM %sOPTIONS")
        args = (__TBL_PREFIX__)
        query = query % args
        cursor.execute(query)
        result = [item[0] for item in cursor.fetchall()]
        cursor.close()
        cnx.close()
        return result

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")

        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        self.container = tk.Frame(self)
        self.container.pack(side="top", fill="both", expand=True)
        self.container.grid_rowconfigure(0, weight=1)
        self.container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            page_name = F.__name__
            frame = F(parent=self.container, controller=self)
            self.frames[page_name] = frame

            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()

    def add_new(self):
        ''' Create a new frame on the run '''
        self.frames["StartPage"] = StartPage(parent=self.container, controller=self)
        self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")         
        self.frames["PageOne"] = PageOne(parent=self.container, controller=self)
        self.frames["PageOne"].grid(row=0, column=0, sticky="nsew")      


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the start page", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)
        i = ini.getById(1)
        o = options.getById(i.lin_option)
        text0 = 'Last option in database is ' + o.symbol
        label = tk.Label(self, text=text0, font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)        

        button1 = tk.Button(self, text="Go to Page One to change options",
                            command=lambda: controller.show_frame("PageOne"))
        button2 = tk.Button(self, text="Go to Page Two to update Page One",
                            command=lambda: controller.show_frame("PageTwo"))       
        button1.pack()
        button2.pack()


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is page 1. Press button to chance selection", font=controller.title_font)
        label.grid(row=0, column=0)

        i = ini.getById(1)
        candidates = options.getall()
        print(str(candidates))
        Order = candidates.index(i.lin_option)

        for counter, lin in enumerate(candidates):       
            file = 1 + counter # First counter is zero
            print('Start file = ' + str(file))
            print ('lin = ' + str(lin))

            o = options.getById(lin)
            print (' o = ' + str(o.lin_id) + ', ' + o.symbol)

            # Cell 0
            if Order == counter :
                label = tk.Button(self, text=(counter+1), fg='red', state="disabled" ) 
            else :                
                label = tk.Button(self, text=(counter+1), fg='blue', command= self.on_click(i, o.lin_id))

            label.grid(row=file, column=0)

            # Cell 1
            if Order == counter :
                label = tk.Label(self, text=o.symbol, font = 'Helvetica 28')
            else :
                label = tk.Label(self, text=o.symbol, font = 'Helvetica 12')

            label.grid(row=file, column=1)
            print ('End file = ' + str(file))
            print ()

        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button.grid()

    def on_click(self, i, lin_id):
        print ('Change db values. OLD initial.lin_choise = ' + str(i.lin_option))
        i.lin_option = lin_id
        i.update()
        print ('Change db values. NEW initial.lin_choise = ' + str(i.lin_option))        

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is page 2", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)
        button1 = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button2 = tk.Button(self, text="Update page 1 and go to the start page",
                           command=self.on_click)       
        button1.pack()
        button2.pack()

    def on_click(self):
        self.controller.add_new()
        self.controller.show_frame("StartPage")            


if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

0 个答案:

没有答案