Python - Select clickable

Asked

Viewed 534 times

0

I have to display on the screen (Tkinter) a list pulled from the database (mysql) containing information about a person (name and id) and make it possible that any item on that list can be clickable and, when clicking on one, select that person’s id and call another function next. How to do this in Python?

2 answers

0

Some considerations, without taking into account that you have already decided to use Tkinter: if it is a real problem to be solved, and not a learning exercise, first you have to choose what technology to use for your program interface: can be a desktop application, which opens its own local window, or can be a web application.

In the second case, your program runs, and runs in the background, but creates nothing on the screen directly. A web browser on the same computer points to a port on the computer itself, provided by the framework used by your program - and all your program has to provide is well formatted HTML, with link elements <a ...> to another view function that can provide the details.

It might scare you if you’ve never done anything like this, but this is the easiest way - even because once done, people can use your program from other computers on the same network, or even on the Internet, without needing to install anything locally.

I would suggest using the Flask micro-framework - do the tutorial, and you’ll see that it’s simple to get to where you want it: https://flask-ptbr.readthedocs.io/en/latest/

The other way I mentioned, with a direct application, requires the use of a library with a graphical Toolkit - which can be Tkinter, which comes installed with Python itself.

Its initial simplicity can hide many problems inherent in the development of graphical interfaces, which HTML solves well by separating the logic of the presentation - in HTML you create a simple document, and then you can tidy up the layout with CSS, without worrying about the logic of your program. Starting from that even if you do a cool tutorial of Tkinter or other Toolkit like GTK+ or Qt, the tutorial will hardly cover examples of usage in conjunction with a database, and how to have clickable data elements on the screen.

By the way, most of the tutorials and documentation of Tkinter and other graphic libraries suffer from an addiction that complicates the development: everyone insists on creating their program as a class that inherits directly from the Window class or other equivalent of the graphic Toolkit. This is unnecessary - your program has a window, not a window - it is perfectly possible to write this without the use of user created classes.

Start by creating a main function that creates the window and the desired components (such as frames, navigation buttons, etc.) as normal variables. I suggest using the complementary "ttk" external library that has the "treeview" widget - without it you will have to re-invent the wheel to make a list of clickable elements with scrollbar: https://tkdocs.com/tutorial/tree.html

In short, it’s not impossible to do it on Tkinter - but I also can’t create the program from scratch for you in this answer. If you choose this, please start your code by creating the window skeleton, desired layout with the use of frames, etc... and I or someone else here can give more tips.

0


The code below uses sqlalchemy to create a table in the database and insert random names, then use tkinter to display a list of these names, and clicking displays the selected name.

Screenshot do programa

BANCO_DE_DADOS = 'mysql://root:password@localhost/nomedobanco'

import sqlalchemy as sa
from sqlalchemy import Column, Unicode, Integer, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

import tkinter as tk
import tkinter.messagebox as tkmsg

Base = declarative_base()
Session = sessionmaker()

class Pessoa(Base):
    __tablename__ = 'pessoas'
    id = Column(Integer(), primary_key=True)
    nome = Column(Unicode(300))

def inicializa_banco(engine):
    Base.metadata.bind = engine
    Base.metadata.create_all()
    Session.configure(bind=engine)

def cria_pessoas_de_teste(num_pessoas=10):
    import random
    import itertools
    nomes = ['Bruno', 'Cláudio', 'Alfredo', 'João']
    sobrenomes = ['Costa', 'Almeida', 'Souza', 'Teixeira']
    nomes_completos = [' '.join(g) for g in itertools.product(nomes, sobrenomes)]
    for n in random.sample(nomes_completos, num_pessoas):
        yield Pessoa(nome=n)

class App:
    def __init__(self, parent):
        self.parent = parent
        self.combo()

    def combo(self):
        self.box_value = tk.StringVar()
        self.box = tk.Listbox(self.parent)
        self.box.bind('<<ListboxSelect>>', self.selecionou)
        s = Session()
        for p in s.query(Pessoa):
            self.box.insert(tk.END, '{0.id} - {0.nome}'.format(p))
        s.close()
        self.box.grid(column=0, row=0)

    def selecionou(self, evt):
        pos = int(self.box.curselection()[0])
        pessoa = self.box.get(pos)
        tkmsg.showinfo(title='Selecionado!', message='Você selecionou {}'.format(pessoa))

if __name__ == '__main__':
    engine = create_engine(BANCO_DE_DADOS, echo=True)
    inicializa_banco(engine)
    s = Session()
    s.add_all(cria_pessoas_de_teste())
    s.commit()
    root = tk.Tk()
    app = App(root)
    root.mainloop()

Remembering that, to work, you have to edit the line with the bank name, user and password.

  • Note that the code uses python 3, if you want to use python 2 you have to change import tkinter as tk for import Tkinter as tk and import tkinter.messagebox as tkmsg for import tkMessageBox as tkmsg

Browser other questions tagged

You are not signed in. Login or sign up in order to post.