help with storing value of a local variable in python

Asked

Viewed 941 times

1

Hello, well, I am writing an application using SQLITE and Python, everything was going well until I had a problem that I am not able to solve, it happens that I have a db of the fipe, so I need to load 3 combobox with mark, model and year, so I decided to do it this way, in the first combobox I carry the marks, then I load the choice with a ".get()", with the reply of ".get()" I would carry the _id in this way:

('SELECT _id FROM tag WHERE name = {}'. format (answered.get())</b

Right after that answer would load the templates with the answer from that select, my problem is that the answer from the ".get()" stays inside my "def Pegamarca(self, Event):" and I’m not being able to use this local variable, I’ve tried to transfer it into a global variable, I’ve tried to add the string by creating an open variable before and then adding it into the function, I’ve tried to do everything that my knowledge is capable but I can’t solve, someone gives me a light, now besides being with the problem I’m curious also to know the solution, I will leave the application code (it has some incomplete parts because I have rewritten it a thousand times to try to solve the problem, but it is better for you to understand my problem).

import tkinter as tk
import tkinter.ttk as ttk
import sqlite3

class Sqlite:
    
    def __init__(self, master):
        self.master = master
        self.db = sqlite3.connect('fdb.db')
        self.cb = ttk.Combobox(master)
        self.cb.pack()
        self.cb['values'] = self.combo_input()
        self.cb.bind("<<ComboboxSelected>>", self.PegarMarca)
        self.cc = ttk.Combobox()
        self.cc.pack()
        self.cc['values'] = self.modelo()
        
    def combo_input(self) -> object:
        cursor = self.db.cursor()
        cursor.execute('SELECT nome FROM marca')
        data = []

        for row in cursor.fetchall():
            data.append(row[0])
        return data

    def PegarMarca(self, event):
        print(self.cb.get())

    def modelo(self) -> object:
        cursor = self.db.cursor ()
        cursor.execute('SELECT _id FROM marca WHERE nome = "{}"')
        data = []

        for row in cursor.fetchall():
            data.append(row[0])
        return data

root = tk.Tk()
Sqlite(root)
root.mainloop()
  • This class is really weird because it calls Sqlite when it is not an instance of Sqlite. It seems to be a form does everything, ie, receives data, manipulates, accesses the database, ie, is anything but a cohesive class. It starts there that makes it easier to have mistakes. That is, fixing the error you are asking would only solve it the wrong way, if it solved. When it starts wrong, the tendency is to try to solve with new mistakes.

2 answers

0

The way it is structured does not facilitate consultations at the bank.

As I do not know the structure of your table we will try to simulate.

Following as an example the following table:

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS `veiculos` (
    `marca` TEXT,
    `modelo`    TEXT,
    `ano`   INTEGER,
    `cor`   TEXT
);
INSERT INTO `veiculos` VALUES ('Fiat','Uno',2000,'Branco');
INSERT INTO `veiculos` VALUES ('Fiat','Palio',2017,'Preto');
INSERT INTO `veiculos` VALUES ('Fiat','Uno',1990,'Roxo');
INSERT INTO `veiculos` VALUES ('Ford','Ka',2015,'Amarelo');
INSERT INTO `veiculos` VALUES ('Fiat','Uno',2000,'Preto');
COMMIT;

I believe that:

  • When selecting the combobox brands the combobox models must be filled.
  • When selecting the combobox model the combobox year must be filled.
  • Finally when selecting the combobox year the vehicles are displayed (or you can put a button that triggers the final event).

Based on the above:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Exemplo Tkinter com SQLite"""
import sqlite3
import tkinter as tk
import tkinter.ttk as ttk


class ConectarDB:
    def __init__(self):
        self.conexao = sqlite3.connect('fdb.db')
        self.cursor = self.conexao.cursor()

    def buscar_marca(self):
        return self.cursor.execute('SELECT DISTINCT marca FROM veiculos').fetchall()

    def busca_modelo(self, marca):
        return self.cursor.execute(
            "SELECT DISTINCT modelo FROM veiculos WHERE marca=? COLLATE NOCASE", (marca,)).fetchall()

    def buscar_ano(self, modelo):
        return self.cursor.execute(
            "SELECT DISTINCT ano FROM veiculos WHERE modelo=? COLLATE NOCASE", (modelo,)).fetchall()

    def buscar_veiculos(self, marca, modelo, ano):
        return self.cursor.execute(
            "SELECT * FROM veiculos WHERE marca=? and modelo=? and ano=? COLLATE NOCASE",
            (marca, modelo, ano,)).fetchall()


class Janela(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        # Coletando informações do monitor
        largura = round(self.winfo_screenwidth() / 2)
        altura = round(self.winfo_screenheight() / 2)
        tamanho = ('%sx%s' % (largura, altura))

        # Título da janela principal.
        self.master.title('Exemplo')
        # Tamanho da janela principal.
        self.master.geometry(tamanho)
        # Gerenciador de layout da janela principal.
        self.pack()

        # Criando uma instancia do banco de dados (Abrindo a conexão).
        self.banco = ConectarDB()

        # Inserindo widgets na janela principal.
        self.criar_widgets()

    def criar_widgets(self):
        # Combobox marcas.
        self.comboboxMarca = ttk.Combobox()
        # Preenchedo o combobox com os valores do banco.
        self.comboboxMarca['values'] = self.banco.buscar_marca()
        # Evento que é disparado quando algo é selecionado.
        self.comboboxMarca.bind('<<ComboboxSelected>>', self.pegar_modelo)
        self.comboboxMarca.pack()

        # Combobox modelo.
        self.comboboxModelo = ttk.Combobox()
        self.comboboxModelo.bind('<<ComboboxSelected>>', self.pegar_ano)
        self.comboboxModelo.pack()

        # Combobox ano.
        self.comboboxAno = ttk.Combobox()
        self.comboboxAno.bind('<<ComboboxSelected>>', self.resultado)
        self.comboboxAno.pack()

        # Listbox que irá exibir os resultados localizados.
        self.listbox = tk.Listbox()
        self.listbox.pack()

    def pegar_modelo(self, event):
        # Coletando o valor que foi selecionado no combobox marca.
        marca = self.comboboxMarca.get()

        # Buscando dados no banco e preenchendo o combobox modelo.
        self.comboboxModelo['values'] = self.banco.busca_modelo(marca=marca)

    def pegar_ano(self, event):
        # Coletando o valor que foi selecionado no combobox modelo.
        modelo = self.comboboxModelo.get()

        # Buscando dados no banco e preenchendo o combobox ano.
        self.comboboxAno['values'] = self.banco.buscar_ano(modelo=modelo)

    def resultado(self, event):
        # Coletando os valores de todos os combobox.
        marca = self.comboboxMarca.get()
        modelo = self.comboboxModelo.get()
        ano = self.comboboxAno.get()

        # Limpando o listbox.
        self.listbox.delete(0, tk.END)

        # Buscando dados no banco e utilizando um
        # laço de repetição para preencher o listbox.
        for veiculo in self.banco.buscar_veiculos(marca=marca, modelo=modelo, ano=ano):
            self.listbox.insert(tk.END, veiculo)


root = tk.Tk()
app = Janela(master=root)
app.mainloop()

I hope it helps you as a reference or for ideas.

0

all right? My suggestion would be to use a class attribute, in which case the result would be visible in it. I would leave the method PegarMarca thus:

def PegarMarca(self, event):
    self.marca = self.cb.get()

Where self.marca is an attribute that stores the value you want. But I must advise you to redo the structure of this class, because it is half banged.

Browser other questions tagged

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