简体   繁体   English

如何从python中的gui连接到mysql数据库

[英]how to connect to mysql database from gui made in python

I have used Tkinter to create radiobuttons through which I would like to increment by one in the database after the submit button is clicked whenever a radiobutton is checked. 我已经使用Tkinter创建了单选按钮,每当选中单选按钮时,单击提交按钮后,我想通过该按钮在数据库中增加一个。

Most important i would like to connect to MySQL database but I don't know what to add in my script. 最重要的是,我想连接到MySQL数据库,但是我不知道要在脚本中添加什么。

from Tkinter import *
root= Tk()
frm=Frame(root,relief=RAISED,borderwidth=5,bg="green" )
Label(frm,text= "PLEASE SELECT CANDIDATE\n OF YOUR CHOICE\n\n\n\n",bg="green").pack()
var = IntVar()
for text, value in [('YOWERI KAGUTA MUSEVENI', 1), ('KIIZA BESIGYE', 2), ('AMAAMA JOHN MBABAZI ', 3),
('KARUNGI SHARON', 4), ('BYAMUKAMA OSCAR', 5),
('MATILDA MOREEN', 6), ('DUNCANS', 7)]:

 Radiobutton(frm, text=text, value=value, variable=var,padx=18,bg="green"
 ).pack(anchor=E, fill=X, padx=18 )
 var.set(0)
frm.pack(pady=10)
btn=Button(frm,text='submit',fg="black",bg="yellow")
btn.pack(anchor=E)
root.title("movie chooser")

root.mainloop()

I am going to guide you step by step to resolve your problem. 我将逐步指导您解决问题。 I assume you have already installed MySQL server on Ubuntu. 我假设您已经在Ubuntu上安装了MySQL服务器。

Whether you are using Tkinter or some other GUI package, the method to implement your goal remains the same. 无论您使用的是Tkinter还是其他GUI软件包,实现目标的方法均保持不变。

What tools do I need to use? 我需要使用哪些工具?

First, you will need to to install a Python database interface that will allow you to communicate with MySQL server using Python. 首先,您需要安装一个Python数据库接口,该接口允许您使用Python与MySQL服务器进行通信。 Here is the exhaustive list of Python MySQL databse interfaces . 这是Python MySQL数据库接口的详尽列表

Which one is better to install? 哪个更好安装? I prefer to talk only about 2 of them that I used myself: MySQLdb and MySQL connector . 我只想谈论我自己使用过的其中两个: MySQLdbMySQL connector

MySQLdb is rather a C library which makes it faster than MySQL connector which is a pure Python library. MySQLdb是一个C库,它比纯Python库的MySQL Connector更快。 For portability it is better to choose the later one. 为了便于携带,最好选择后一种。 For speed you need to choose the first one. 为了提高速度,您需要选择第一个。 Note that Django uses MySQLdb. 请注意, Django使用MySQLdb。 That is also my favorite database interface I am going to use in what follows. 那也是我接下来将要使用的我最喜欢的数据库接口。 You can find a good comparison between these 2 interfaces here . 您可以在此处找到这两个接口之间的比较。

How to install MySQLdb on Ubuntu 14.04.3 LTS? 如何在Ubuntu 14.04.3 LTS上安装MySQLdb?

The common way to install MySQLdb is to use pip as described here . 安装MySQLdb的常用方法是使用PIP描述这里 But for Ubuntu, by my personal experience, I prefer to install it this way: 但是对于Ubuntu,根据我的个人经验,我更喜欢这样安装:

  • Install the needed dependencies: sudo apt-get install build-essential python-dev libmysqlclient-dev 安装所需的依赖项: sudo apt-get install build-essential python-dev libmysqlclient-dev
  • Install the MySQL databse interface itself: sudo apt-get install python-mysqldb . 安装MySQL数据库接口本身: sudo apt-get install python-mysqldb

Now you should be able to import it: >>> import MySQLdb 现在您应该能够导入它: >>> import MySQLdb

Interface design 界面设计

First, we'll ask the user to type his credentials to MySQL server: 首先,我们将要求用户在MySQL服务器上键入其凭据:

在此处输入图片说明

If the credentials are wrong, the window still prompts itself there unless the user exists the application. 如果凭据错误,除非用户存在该应用程序,否则窗口仍会提示自己。

If the credentials are the right one, the user may then save/add his favorite starts to the database through a new window similar to the one you designed: 如果凭据是正确的,则用户可以通过类似于您设计的窗口的新窗口将自己喜欢的开始保存/添加到数据库中:

在此处输入图片说明

Implementing the application: 实施应用程序:

1. Database design: 1.数据库设计:

I choose the simplest one, just to satisfy this immediate need: 我选择最简单的一种,只是为了满足这一迫切需求:

mysql> CREATE DATABASE begueradj;

Now it is time to create the table in which we save your favorite stars. 现在是时候创建我们用来保存您喜欢的星星的表了。 It will contains their names starname and an auto incrementing primary key id : 它将包含它们的名称starname和一个自动递增的主键id

mysql> USE begueradj;
mysql> CREATE TABLE mystars(id INT(2) NOT NULL AUTO_INCREMENT,
                            starname VARCHAR(40) NOT NULL,
                            PRIMARY KEY(id)
                            );

2. First interface implementation: 2.第一个接口实现:

The interface represented by the first screenshot is created by initialize_user_interface() function: 第一个屏幕截图表示的界面是由initialize_user_interface()函数创建的:

def initialize_user_interface(self):
        """Draw a user interface allowing the user to type
        MySQL server credentials
        """
        self.parent.title("DB operations")       
        self.parent.grid_rowconfigure(0,weight=1)
        self.parent.grid_columnconfigure(0,weight=1)
        self.parent.config(background="lavender")

        self.label_user=Tkinter.Label(self.parent,text="DB User: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_password=Tkinter.Label(self.parent,text="DB Password:", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")

        self.label_user.grid(row=0,column=0,sticky=Tkinter.E+Tkinter.W)
        self.label_password.grid(row=1,column=0, sticky=Tkinter.E+Tkinter.W)

        self.dbuser=Tkinter.Entry(self.parent)
        self.dbpassword=Tkinter.Entry(self.parent,show="*")

        self.dbuser.grid(row=0,column=1,sticky=Tkinter.E+Tkinter.W)
        self.dbpassword.grid(row=1,column=1,sticky=Tkinter.E+Tkinter.W)

        self.connectb=Tkinter.Button(self.parent,text="Log in",font="Helvetica 10 bold",command=self.dbconnexion)
        self.cancelb=Tkinter.Button(self.parent,text="Cancel",command=self.parent.quit,font="Helvetica 10 bold")

        self.connectb.grid(row=2,column=1,sticky=Tkinter.W)
        self.cancelb.grid(row=2,column=2)

Mainly, I bind the function dbconnexion() to the login button self.connectb : 我主要将函数dbconnexion()绑定到登录按钮self.connectb

def dbconnexion(self): 
        """ Pop up a new window if the credentials are the right ones
        """       
        if self.dbuser.get()=="beueradj" and  self.dbpassword.get()=="begueradj":
            # Pop up the new interface if credentials are OK
            self.item_insertion_window()
        else:
            # Loop over the login interface if not
            self.initialize_user_interface()

3. Second interface implementation: 3.第二接口实现:

If the credentials are right, then display insertion window to add the favorite stars to the database. 如果凭据正确,则显示插入窗口以将收藏的星星添加到数据库。 To pop up the new window you need to use Tkinter.Toplevel() method. 要弹出新窗口,您需要使用Tkinter.Toplevel()方法。

This is done by the function item_insertion_window() : 这是通过函数item_insertion_window()

def item_insertion_window(self):
        """ Display the stars to add to the database
        Group the stars using radio buttons
        """
        self.new_window=Tkinter.Toplevel(self)
        self.new_window.wm_title("Add my favorite stars")
        self.new_window.grid_rowconfigure(0, weight=1)
        self.new_window.grid_columnconfigure(0, weight=1)

        self.exitb=Tkinter.Button(self.new_window,text="Exit",command=self.new_window.quit)
        self.submitb=Tkinter.Button(self.new_window,text="Submit",command=self.increment_db)
        self.exitb.grid(row=8,column=1)
        self.submitb.grid(row=8,column=0,sticky=Tkinter.W)

        self.v=IntVar()
        self.tvstars=[('YOWERI KAGUTA MUSEVENI', 1), ('KIIZA BESIGYE', 2), 
                      ('AMAAMA JOHN MBABAZI ', 3), ('KARUNGI SHARON', 4), 
                      ('BYAMUKAMA OSCAR', 5), ('MATILDA MOREEN', 6), 
                      ('DUNCANS', 7)]
        self.i=0
        for self.txt, star in self.tvstars:
            self.i=self.i+1
            self.rb=Tkinter.Radiobutton(self.new_window,text=self.txt,variable=self.v,value=star)
            self.rb.grid(row=self.i,column=0,sticky=Tkinter.W)

4. How to get the Tkinter radiobutton text? 4.如何获取Tkinter单选按钮文本?

In the official documentation, there is only a way to retrieve the value of the radio button which is picked, but no way is mentioned to get the text (names of the stars) which actually interests us. 在官方文档中,只有一种方法可以检索所选择的单选按钮的值,但是没有提到获取我们真正感兴趣的文本(星星的名称)的方法。 I did not find any post on StackOverflow dealing with this subject either. 我也没有在StackOverflow上找到任何与此主题相关的帖子。 My hack is to code a dictionary to map the radio button values to the corresponding star's name using which_artist() function: 我的技巧是编写编码字典,以使用which_artist()函数将单选按钮值映射到相应星星的名称:

def which_artist(self,radiob):
        """Return star's name
        """
        self.artists = {
                        1:"YOWERI KAGUTA MUSEVENI",
                        2:"KIIZA BESIGYE",
                        3:"AMAAMA JOHN MBABAZI",
                        4:"KARUNGI SHARON",
                        5:"BYAMUKAMA OSCAR",
                        6:"MATILDA MOREEN",
                        7:"DUNCANS",
        }
        return self.artists.get(radiob,"Unknown")

This function will be useful in the following step. 此功能在以下步骤中将很有用。

5. Adding your favorite star to the database: 5.将您喜欢的星星添加到数据库中:

First, you may save your MySQL server parameters in a configuration file config.py , but as our project is small and apparently you are not going to extend it any further in the futur, let's save these credentials within a function itself: 首先,您可以将MySQL服务器参数保存在配置文件config.py ,但是由于我们的项目很小,而且显然您不会在将来进一步扩展它,所以我们将这些凭据保存在函数本身中:

self.config = {
                  'user': 'begueradj',
                  'passwd': 'begueradj',
                  'host': '127.0.0.1',
                  'db': 'begueradj',
        }

Here is the function that implements the insertion: 这是实现插入的功能:

def increment_db(self):
    """ Insert the selected favorite star into the database.
    """
    self.chosenartist=self.which_artist(self.v.get())
    print self.chosenartist

    self.config = {
              'user': 'begueradj',
              'passwd': 'bregredj',
              'host': '127.0.0.1',
              'db': 'begueradj',
    }
    try:
        self.connecttodb=MySQLdb.connect(**self.config)
    except MySQLdb.Error:
        print"Connexion error"

    self.cursor=self.connecttodb.cursor()

    self.cursor.execute("""INSERT INTO testtable(starname) VALUES(%s)""",self.chosenartist)

    self.connecttodb.commit()
    self.connecttodb.close()

Of course, you will need to change the configuration dictionary self.config according to your own settings. 当然,您将需要根据自己的设置更改配置字典self.config

Also, it is more suitable to bind self.connecttodb.close() to the exit button self.exitb instead. 同样,将self.connecttodb.close()绑定到退出按钮self.exitb更合适。 6. The application: 6.申请:

Here is the full program: 这是完整的程序:

'''
Created on Feb 29, 2016

@author: begueradj
'''
import Tkinter
import MySQLdb
from Tkinter import IntVar


class Begueradj(Tkinter.Frame):
    '''
    classdocs
    '''


    def __init__(self, parent):
        '''
        Constructor
        '''
        Tkinter.Frame.__init__(self, parent)
        self.parent=parent
        self.initialize_user_interface()

    def initialize_user_interface(self):
        """Draw a user interface allowing the user to type
        MySQL server credentials
        """
        self.parent.title("DB operations")       
        self.parent.grid_rowconfigure(0,weight=1)
        self.parent.grid_columnconfigure(0,weight=1)
        self.parent.config(background="lavender")

        self.label_user=Tkinter.Label(self.parent,text="DB User: ",anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")
        self.label_password=Tkinter.Label(self.parent,text="DB Password:", anchor=Tkinter.W,background="dark slate gray",foreground="white", font="Helvetica 8  bold")

        self.label_user.grid(row=0,column=0,sticky=Tkinter.E+Tkinter.W)
        self.label_password.grid(row=1,column=0, sticky=Tkinter.E+Tkinter.W)

        self.dbuser=Tkinter.Entry(self.parent)
        self.dbpassword=Tkinter.Entry(self.parent,show="*")

        self.dbuser.grid(row=0,column=1,sticky=Tkinter.E+Tkinter.W)
        self.dbpassword.grid(row=1,column=1,sticky=Tkinter.E+Tkinter.W)

        self.connectb=Tkinter.Button(self.parent,text="Log in",font="Helvetica 10 bold",command=self.dbconnexion)
        self.cancelb=Tkinter.Button(self.parent,text="Cancel",command=self.parent.quit,font="Helvetica 10 bold")

        self.connectb.grid(row=2,column=1,sticky=Tkinter.W)
        self.cancelb.grid(row=2,column=2)

    def item_insertion_window(self):
        self.new_window=Tkinter.Toplevel(self)
        self.new_window.wm_title("Add my favorite stars")
        self.new_window.grid_rowconfigure(0, weight=1)
        self.new_window.grid_columnconfigure(0, weight=1)

        self.exitb=Tkinter.Button(self.new_window,text="Exit",command=self.new_window.quit)
        self.submitb=Tkinter.Button(self.new_window,text="Submit",command=self.increment_db)
        self.exitb.grid(row=8,column=1)
        self.submitb.grid(row=8,column=0,sticky=Tkinter.W)

        self.v=IntVar()
        self.tvstars=[('YOWERI KAGUTA MUSEVENI', 1), ('KIIZA BESIGYE', 2), 
                      ('AMAAMA JOHN MBABAZI ', 3), ('KARUNGI SHARON', 4), 
                      ('BYAMUKAMA OSCAR', 5), ('MATILDA MOREEN', 6), 
                      ('DUNCANS', 7)]
        self.i=0
        for self.txt, star in self.tvstars:
            self.i=self.i+1
            self.rb=Tkinter.Radiobutton(self.new_window,text=self.txt,variable=self.v,value=star)
            self.rb.grid(row=self.i,column=0,sticky=Tkinter.W)


    def which_artist(self,radiob):
        self.artists = {
                        1:"YOWERI KAGUTA MUSEVENI",
                        2:"KIIZA BESIGYE",
                        3:"AMAAMA JOHN MBABAZI",
                        4:"KARUNGI SHARON",
                        5:"BYAMUKAMA OSCAR",
                        6:"MATILDA MOREEN",
                        7:"DUNCANS",
        }
        return self.artists.get(radiob,"Unknown")

    def increment_db(self):
        #print self.v.get()
        self.chosenartist=self.which_artist(self.v.get())
        print self.chosenartist

        self.config = {
                  'user': 'begueradj',
                  'passwd': 'begueradj',
                  'host': '127.0.0.1',
                  'db': 'begueradj',
        }
        try:
            self.connecttodb=MySQLdb.connect(**self.config)
        except MySQLdb.Error:
            print"Connexion error"

        self.cursor=self.connecttodb.cursor()

        self.cursor.execute("""INSERT INTO mystars(starname) VALUES(%s)""",self.chosenartist)

        self.connecttodb.commit()
        self.connecttodb.close()



    def dbconnexion(self):        
        if self.dbuser.get()=="begueradj" and  self.dbpassword.get()=="begueradj":
            self.item_insertion_window()
        else:
            self.initialize_user_interface()



def main():
    root=Tkinter.Tk()
    d=Begueradj(root)
    root.mainloop()

if __name__=="__main__":
    main()

7. Demo 7.演示

I inserted one star through the Tkinter interface. 我通过Tkinter界面插入了一颗星星。 Let's check if that was effective: 让我们检查一下是否有效:

mysql> SELECT * FROM begueradj.mystars;
+----+------------------------+
| id | starname               |
+----+------------------------+
|  1 | YOWERI KAGUTA MUSEVENI |
+----+------------------------+
1 row in set (0.00 sec)

Hope this helps. 希望这可以帮助。

UPDATE: 更新:

You asked me about how to update but your comments are not clear to me when it comes to understanding the logic of your update statement. 您问我有关如何更新的信息,但是在理解更新语句的逻辑时,您的评论对我来说并不明确。 So I am answering here only according to the small piece of code your comment shows. 因此,我仅根据您的注释显示的一小段代码在此处回答。

You seem to want to check which radio button is selected through your statement: self.var.get() and increment something by 1 (and that is why I do not understand your update statement: so whatever the radiobutton which is pressed you do the same action; which thing means the radio buttons are meaningless). 您似乎想检查通过以下语句选择了哪个单选按钮: self.var.get()并增加1(这就是为什么我不理解您的update语句的原因:所以无论按下哪个单选按钮,您都可以同样的动作;这意味着单选按钮是没有意义的)。

If you want to do that in the perspective of some mysterious test of your own though, you will need to use variable option and bind a method to the command option for each radiobutton you created. 但是,如果您想从自己的神秘测试角度出发,则需要使用variable选项并将每个创建的单选按钮的方法绑定到command选项。

To use the variable option, you will need to run this first: 要使用variable选项,您首先需要运行以下命令:

self.v = IntVar()

Then, for each radiobutton you set: variable=self.v and command = self.get_radiobutton_id 然后,为您设置的每个variable=self.v按钮: variable=self.vcommand = self.get_radiobutton_id

The method in question must return the identifier of the selected radiobutton: 有问题的方法必须返回所选单选按钮的标识符:

self defself.get_radiobutton_id(self):
   return v.get()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM