Community!
While using pyodbc with pandas, I discovered something that is, at least to me, strange.
When running the program, everything works out as intended, however I seem to be missing one row for the resulting DataFrame.
I ran the exact same query in SSMS, and the result should show 2 rows.
Printing the DataFrame to console, I see that it only shows the latter of the resulting rows.
What am I not seeing? Any settings in pd.set_option-part I've done wrong? I've tried to change these, without luck so far.
import tkinter as tk
from tkinter import Tk, W, E
from tkinter.ttk import Frame, Button, Entry, Style, Radiobutton, Label
from tkinter import filedialog as fd
import os
class Application(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#------------------------------#
# Functions #
#------------------------------#
def SQL_Query(query_string):
import pyodbc as p # MIT Lisence. OK
import itertools
import pandas as pd # BSD Lisence. OK
pd.set_option("display.max_rows", None)
pd.set_option("display.max_columns", None)
pd.set_option("display.width", 1000)
databaseName = '***'
username = '***'
password = '***'
server = '***'
driver = '***'
CONNECTION_STRING = 'DRIVER='+driver+';SERVER='+server+';DATABASE='+databaseName+';UID='+username+';PWD='+ password
conn = p.connect(CONNECTION_STRING)
cursor = conn.cursor()
cursor.execute(query_string)
row = cursor.fetchone()
desc = cursor.description
column_names = [col[0] for col in desc]
data = [dict(zip(column_names, row))
for row in cursor.fetchall()]
conn.close()
df = pd.DataFrame(data)
if df.empty == False:
qty_total = str(df['InitialQuantity'].sum())
qty_RT = str(df['RT'].sum())
print('Number of units found with criteria: ' + qty_total)
print('Numbe rof units with RT: ' + qty_RT + '\n')
print(df)
def btnRun():
line = var.get()
mat = varMaterial.get()
if line == "('1', '6', '8', '18')":
query = f"""QueryStringIsHere"""
SQL_Query(query)
elif line == "('3', '10')":
query = f"""QueryStringIsHere"""
SQL_Query(query)
#------------------------------#
# Program title and attributes #
#------------------------------#
self.master.title("Production Orders")
Style().configure("TButton", padding=(0, 5, 0, 5),
font='serif 10')
self.columnconfigure(0, pad=3)
self.columnconfigure(1, pad=3)
self.columnconfigure(2, pad=3)
self.columnconfigure(3, pad=3)
self.rowconfigure(0, pad=3)
self.rowconfigure(1, pad=3)
#------------------------------#
# UI Elements #
#------------------------------#
var = tk.StringVar() #variable to hold radio button values
varMaterial = tk.StringVar()
rad12 = Radiobutton(self,text="x", variable=var, value = "('1', '6', '8', '18')").grid(row=0, column=0, sticky=W)
rad36 = Radiobutton(self,text="y", variable=var, value = "('3', '10')").grid(row=1, column=0, sticky=W)
entry = Entry(self, textvariable=varMaterial).grid(row=2, column=1, columnspan=4, sticky=W+E)
lblEntry = Label(self, text="Material Number:").grid(row=2, column=0,columnspan=1, sticky=W+E)
#------------------------------#
# Command buttons #
#------------------------------#
btnSelect = Button(self, text="Run Query", command = btnRun).grid(row=3, column=0)
btnClear = Button(self, text="Clear text", command = '').grid(row=3, column=1)
btnQuit = Button(self, text="Quit", command = self.master.destroy).grid(row=3, column=4)
#------------------------------#
# Packing #
#------------------------------#
self.pack()
def main():
root = Tk()
app = Application()
root.mainloop()
if __name__ == '__main__':
main()
The solution to this problem was found with guidance from comments on original post. As I was doing a .fetchone() first, and then populating the DataFrame with .fetchall(), data did not include the first resulting row.
import tkinter as tk
from tkinter import Tk, W, E
from tkinter.ttk import Frame, Button, Entry, Style, Radiobutton, Label
from tkinter import filedialog as fd
import os
class Application(Frame):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#------------------------------#
# Functions #
#------------------------------#
def SQL_Query(query_string):
import pyodbc as p # MIT Lisence. OK
import itertools
import pandas as pd # BSD Lisence. OK
pd.set_option("display.max_rows", None)
pd.set_option("display.max_columns", None)
pd.set_option("display.width", 1000)
databaseName = '***'
username = '***'
password = '***'
server = '***'
driver = '***'
CONNECTION_STRING = 'DRIVER='+driver+';SERVER='+server+';DATABASE='+databaseName+';UID='+username+';PWD='+ password
conn = p.connect(CONNECTION_STRING)
cursor = conn.cursor()
cursor.execute(query_string)
desc = cursor.description
column_names = [col[0] for col in desc]
data = [dict(zip(column_names, row))
for row in cursor.fetchall()]
conn.close()
df = pd.DataFrame(data)
if df.empty == False:
qty_total = str(df['InitialQuantity'].sum())
qty_RT = str(df['RT'].sum())
print('Number of units found with criteria: ' + qty_total)
print('Numbe rof units with RT: ' + qty_RT + '\n')
print(df)
def btnRun():
line = var.get()
mat = varMaterial.get()
if line == "('1', '6', '8', '18')":
query = f"""QueryStringIsHere"""
SQL_Query(query)
elif line == "('3', '10')":
query = f"""QueryStringIsHere"""
SQL_Query(query)
#------------------------------#
# Program title and attributes #
#------------------------------#
self.master.title("Production Orders")
Style().configure("TButton", padding=(0, 5, 0, 5),
font='serif 10')
self.columnconfigure(0, pad=3)
self.columnconfigure(1, pad=3)
self.columnconfigure(2, pad=3)
self.columnconfigure(3, pad=3)
self.rowconfigure(0, pad=3)
self.rowconfigure(1, pad=3)
#------------------------------#
# UI Elements #
#------------------------------#
var = tk.StringVar() #variable to hold radio button values
varMaterial = tk.StringVar()
rad12 = Radiobutton(self,text="x", variable=var, value = "('1', '6', '8', '18')").grid(row=0, column=0, sticky=W)
rad36 = Radiobutton(self,text="y", variable=var, value = "('3', '10')").grid(row=1, column=0, sticky=W)
entry = Entry(self, textvariable=varMaterial).grid(row=2, column=1, columnspan=4, sticky=W+E)
lblEntry = Label(self, text="Material Number:").grid(row=2, column=0,columnspan=1, sticky=W+E)
#------------------------------#
# Command buttons #
#------------------------------#
btnSelect = Button(self, text="Run Query", command = btnRun).grid(row=3, column=0)
btnClear = Button(self, text="Clear text", command = '').grid(row=3, column=1)
btnQuit = Button(self, text="Quit", command = self.master.destroy).grid(row=3, column=4)
#------------------------------#
# Packing #
#------------------------------#
self.pack()
def main():
root = Tk()
app = Application()
root.mainloop()
if __name__ == '__main__':
main()
Related
This a simple code in which i have created a text area using tkinter and a menu in which there is a option of find and replace in which if user click on it then a gui will appear in which user will enter a word to whom they want to replace and then a word to whom they want replace with but till now i have just created a gui . But how can i replace word with a word given by user with the text of text area that i have created.
from tkinter import *
import tkinter.font as font
from tkinter import messagebox
root = Tk()
root.title("MyCodeEditor")
editor = Text()
editor.pack()
menu_bar = Menu(root)
def find_replace():
f = Tk()
f.title("Find and Replace")
find_label = Label(f,text = "Find : ")
replace_label = Label(f,text = "Replace : ")
find_label.grid(row = 0 , column = 0)
replace_label.grid(row = 3 , column = 0)
global find_enter
global replace_enter
find_enter = Entry(f,fg = "black" , background = "blue",borderwidth = 5,width = 40)
replace_enter = Entry(f,fg = "black" , background = "blue", borderwidth = 5, width =40 )
find_enter.grid(row = 0 , column = 1)
replace_enter.grid(row = 3 , column = 1)
btn_replace = Button(f,text = 'Replace',fg = 'black',command = None)
btn_replace.grid(row=0, column = 5)
format_bar = Menu(menu_bar , tearoff = 0)
format_bar.add_command(label = 'Find and Replace',command = find_replace)
menu_bar.add_cascade(label = 'Format' ,menu = format_bar )
root.config(menu = menu_bar)
root.mainloop()
Here is a simple example (most of it is just the GUI looks, the main part is the actual replace method):
from tkinter import Tk, Text, Entry, Frame, Button, Toplevel, Label, Menu, TclError, IntVar
normal_font = ('comicsans', 10)
class FindAndReplace(Toplevel):
def __init__(self, parent, text_widget: Text):
Toplevel.__init__(self, parent)
self.focus_force()
self.title('Find and Replace')
self.geometry('500x200')
self.resizable(False, False)
self.parent = parent
self.widget = text_widget
try:
self.start_index = self.widget.index('sel.first')
self.end_index = self.widget.index('sel.last')
except TclError:
self.start_index = '1.0'
self.end_index = 'end'
self.to_find = None
self.to_replace = None
# creating find entry
find_frame = Frame(self)
find_frame.pack(expand=True, fill='both', padx=20)
Label(find_frame, text='Find:', font=normal_font).pack(side='left', fill='both', padx=20)
self.find_entry = Entry(find_frame)
self.find_entry.pack(side='right', expand=True, fill='x')
# creating replace entry
replace_frame = Frame(self)
replace_frame.pack(expand=True, fill='both', padx=20)
Label(replace_frame, text='Replace:', font=normal_font).pack(side='left', fill='both', padx=20)
self.replace_entry = Entry(replace_frame)
self.replace_entry.pack(side='right', expand=True, fill='x')
# creating buttons
button_frame = Frame(self)
button_frame.pack(expand=True, fill='both', padx=20)
Button(button_frame, text='Cancel', font=normal_font,
command=self.destroy).pack(side='right', fill='x', padx=5)
Button(button_frame, text='Replace', font=normal_font,
command=self.replace).pack(side='right', fill='x', padx=5)
def __find_get(self):
self.to_find = self.find_entry.get()
def __replace_get(self):
self.to_replace = self.replace_entry.get()
def replace(self):
self.__find_get()
self.__replace_get()
if not self.to_replace:
return
length = IntVar()
index = self.widget.search(self.to_find, self.start_index, stopindex=self.end_index, count=length)
end_index = self.widget.index(index + f'+{length.get()}c')
self.widget.delete(index, end_index)
self.widget.insert(index, self.to_replace)
root = Tk()
menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='File', menu=file_menu)
file_menu.add_command(label='Find and Replace', command=lambda: FindAndReplace(root, text))
root.config(menu=menu_bar)
text = Text(root)
text.pack()
root.mainloop()
Obviously some other functionality could be added such as replace all
Here's the code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
class TwitterBot:
def __init__(self, username, password):
self.username = username
self.password = password
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
sasha = TwitterBot(entry_user.get(), entry_pass.get())
The entry never send the values I typed in into sasha = TwitterBot(entry, entry2)
Meaning I want that inside tkinter interface, I type in two entries that supposed to be username and password and when I execute the function those values get injected. I think the problem is that self.username and self.password are defined inside of the __init__ and so if those entries stay empty at the launch so i cant get them to inject. cause I can print my entry.get() values. I just cant make them replace the two first parameters of my __init__ function. Does anybody knows how to help?
Try this:
import tkinter as tk
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def create_bot(event=None):
sasha = TwitterBot(entry_user.get(), entry_pass.get())
print("started bot")
root = tk.Tk()
entry_user = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand=True)
# Log in if the user presses the Enter key:
entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand=True)
# Log in if the user presses the Enter key:
entry_pass.bind("<Return>", create_bot)
button = tk.Button(root, text="Log in", command=create_bot)
button.pack()
root.mainloop()
Your code wasn't working because as soon as your code created the entries it tried to get the data out of them (which obviously is an empty string) and created the TwitterBot object. To make it work you have to give the user time to enter their details in the entries by adding a button/binding to the user pressing the Enter key.
I created a button and placed it at the bottom of the window. When you click the button it calls create_bot which creates the TwitterBot object.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
import tkinter as tk
from tkinter import *
from tkmacosx import Button as button
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def open_br(self):
self.bot = webdriver.Firefox()
def end_br(self):
self.bot.quit()
def login(self):
bot = self.bot
bot.get("http://twitter.com/login/")
time.sleep(3)
email = bot.find_element_by_name("session[username_or_email]")
password = bot.find_element_by_name("session[password]")
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
password.send_keys(Keys.RETURN)
time.sleep(3)
def like_tweet(self, hashtag):
bot = self.bot
bot.get('https://twitter.com/search?q='+hashtag+'&src=typed_query')
time.sleep(3)
for i in range(1,8):
bot.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
tweets = bot.find_elements_by_class_name('tweet')
tweetLinks = [i.get_attribute('href') for i in bot.find_elements_by_xpath("//a[#dir='auto']")]
filteredTweet = list(filter(lambda x: 'status' in x,tweetLinks))
print(filteredTweet)
for link in filteredTweet:
bot.get(link)
time.sleep(5)
if drop2_var.get() == "Retweet":
try:
bot.find_element_by_xpath("//div[#data-testid='retweet']").click()
bot.find_element_by_xpath("//div[#data-testid='retweetConfirm']").click()
time.sleep(3)
except Exception as ex:
time.sleep(10)
elif drop2_var.get() == "Likes":
bot.find_element_by_xpath("//div[#data-testid='like']").click()
time.sleep(3)
# def create_bot(event=None):
# sasha = TwitterBot(entry_user.get(), entry_pass.get())
# print("started bot")
sasha = TwitterBot("", "")
root = tk.Tk()
HEIGHT = 800
WIDTH = 400
#FUNCTIONS CLEARING ENTRY
def del_value(event): # note that you must include the event as an arg, even if you don't use it.
entry.delete(0, "end")
return None
def del_value_user(event): # note that you must include the event as an arg, even if you don't use it.
entry_user.delete(0, "end")
return None
def del_value_pass(event): # note that you must include the event as an arg, even if you don't use it.
entry_pass.delete(0, "end")
return None
def ex():
root.quit()
#PROGRAM SETTINGS
root.title("Social Bot")
root.minsize(400, 800)
#root.iconbitmap("/Users/sashakharoubi/Desktop/BOOTCAMP/Week 9/Day 2/image/logo.ico")
root.config(background="#66b3ff")
canvas = tk.Canvas(root, height= HEIGHT, width = WIDTH, bd=0, highlightthickness = 0)
canvas.pack()
# background_image = tk.PhotoImage(file = 'blue.png')
# background_label = tk.Label(root, image =background_image)
# background_label.place(x=0, y=0, relwidth=1, relheight=1)
#MAINFRAME
frame = tk.Frame(root, bg="#222f3e")
frame.place(relx = 0, rely = 0, relwidth = 1, relheight = 1)
#SUBPART FRAME
lower_frame = tk.Frame(root, bg="#E9E9E9", bd=0, highlightthickness = 0, relief="sunken")
#DROPDOWN MENU OPTIONS
OPTIONS = [
"Twitter",
"Instagram(not working)"
]
OPTIONS2 = [
"Likes",
"Retweet"
]
entry_txt = tk.Label(lower_frame, text="Welcome to Social Bot\n\nChoose an action to execute", font=("Montserrat", 15), bg="#E9E9E9", fg="black")
entry_txt.pack(expand = "yes")
#DROPDOWN MENU
drop_var = StringVar(lower_frame)
drop_var.set(OPTIONS[0])
drop2_var = StringVar(lower_frame)
drop2_var.set(OPTIONS2[0])
drop = OptionMenu(lower_frame, drop_var, *OPTIONS)
drop.config(fg="black")
drop.pack()
drop2 = OptionMenu(lower_frame, drop2_var, *OPTIONS2)
drop2.config(fg="black")
drop2.pack()
#ENTRIES
entry = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry.insert(0, "-->Topic to like or retweet")
entry.bind("<Button-1>", del_value)
entry.pack(expand = "yes")
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_user.insert(0, "----Type Your Username---")
entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
#entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_pass.insert(0, "----Type Your Password---")
entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
#entry_pass.bind("<Return>", create_bot)
#BUTTONS
button_confirm = button(lower_frame, text="Confirm", bg="white", fg="black")
button_confirm.pack(pady=25, side = 'top')
button_open = button(lower_frame, text="Open Browser", bg="white", fg="black", command= sasha.open_br)
button_open.pack(pady=25, side = 'top')
button_log = button(lower_frame, text="LOG IN", bg='#54a0ff', fg="white", command =sasha.login, bd=0, highlightthickness = 0)
button_log.pack(pady=25, side = 'left')
button_launch = button(lower_frame, text="START", bg='#1dd1a1', fg="white", relief="flat", command = lambda: sasha.like_tweet(entry.get()), bd=0, highlightthickness = 0)
button_launch.pack(pady=25, side = 'right')
button_stop = button(lower_frame, text="STOP", bg="#ff6b6b", fg="white", command= sasha.end_br)
button_stop.pack(pady=25, side = 'bottom')
button_exit = button(lower_frame, text="Exit", bg ="white", fg="black", command= ex)
button_exit.pack(side = 'bottom')
lower_frame.place(relx = 0.1, rely = 0.1, relwidth=0.8, relheight=0.8)
#TITLE
label = tk.Label(frame, text="S O C I A L B O T", font=("Montserrat", 25), bg="white", fg="#222f3e")
label.pack(side="top", fill ="both")
root.mainloop()
v1 = browser.find_element_by_xpath("").text
try put .text at last of your code
then you can print or use v1 as a value
I need help inserting text in a Text widget that's part of a Frame.
class Test_frame(Frame):
def __init__(self):
Frame.__init__(self)
self.config(width = 700, height = 450)
self.logs_frame = LabelFrame(self, height = 402, width = 348, text = 'Logs')
self.logs_frame.grid(column = 1, row = 0, pady=10, sticky = N)
self.logs_frame.grid_propagate(0)
self.text_box = Text(self.logs_frame, width=40, pady=10, height=22)
self.text_box.pack(side="left")
self.scroll_y = Scrollbar(self.logs_frame, orient="vertical", command=self.text_box.yview)
self.scroll_y.pack(side="left", expand=True, fill="y")
self.text_box.configure(yscrollcommand=self.scroll_y.set)
self.text_box.insert (?????.END, "Sample Text")
I have no idea how to access that Text widget now.
Test_frame is part of a Notebook:
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.my_notebook = ttk.Notebook(self)
self.my_notebook.pack(pady = 5)
self.frames = {}
for F in (Test_frame, Final_flash_frame):
frame = F()
self.frames[F] = frame
frame.pack(fill = 'both', expand = 1)
self.my_notebook.add(self.frames[Test_frame], text = "Testing")
I created a minimal source, but I guess you solved your problem.
I added a little button to add text, and added some text from outside the class.
Here it is, anyway:
import tkinter as Tk
import tkinter.ttk as ttk
from tkinter import *
def BumpText(textbox):
textbox.insert(END,", MORE TEXT")
class Test_frame(Frame):
def __init__(self):
Frame.__init__(self)
self.config(width = 700, height = 450)
self.logs_frame = LabelFrame(self, height = 402, width = 348, text = 'Logs')
self.logs_frame.grid(column = 1, row = 0, pady=10, sticky = N)
self.logs_frame.grid_propagate(0)
self.text_box = Text(self.logs_frame, width=40, pady=10, height=22)
self.text_box.pack(side="left")
self.scroll_y = Scrollbar(self.logs_frame, orient="vertical", command=self.text_box.yview)
self.scroll_y.pack(side="left", expand=True, fill="y")
self.text_box.configure(yscrollcommand=self.scroll_y.set)
self.text_box.insert(END, "Sample Text")
self.button = Button(self.logs_frame, text="Add\nText", command=lambda:self.text_box.insert(END, ", More Text"))
self.button.pack(side="bottom")
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.my_notebook = ttk.Notebook(self)
self.my_notebook.pack(pady = 5)
self.frames = {}
for F in (Test_frame,): # , Final_flash_frame):
frame = F()
self.frames[F] = frame
frame.pack(fill = 'both', expand = 1)
self.my_notebook.add(self.frames[Test_frame], text = "Testing")
for F,f in self.frames.items():
try:
f.text_box.insert(END," (Added by App)")
except Exception as e:
pass # ignore frames without text_box
if __name__ == "__main__":
App().mainloop()
Ok, so apparently just using:
self.text_box.insert (END, "Sample Text")
works
Cheers,
A
I'm making GUI the first time with tkinter(python), and I want to show the results in the same place, where they are at the beginning.
When I run this code the functions are fully working, but I cannot show the results in my label.
The button have to take data from Entries and give it to the function with data from drop-down list.
The results should overwrite the list as1, as2 = [0, 0] and then show the results on the label result_1, result_2
I've tried to add "master" parameter to the function - onclick, but then the GUI was running without clicking the button.
# coding=utf-8
from tkinter import *
def function_1(h, eta_bet):
print(h, eta_bet)
return h, eta_bet
def calculated_value_concrete(class_concrete): # could be 20/25
eta_bet = class_concrete
return eta_bet
class Menu:
def __init__(self, master):
container = Label(master, bg="#003366")
container.pack()
menu_bg = Label(container, bg="#003366", fg="white", pady=15)
countings_bg = Label(container)
self.button1 = Button(menu_bg, text="Zbrojenie symetryczne", command=lambda: self.onclick(1, countings_bg),
width=20)
menu_bg.pack(side=LEFT, fill=Y)
self.button1.pack()
def onclick(self, args, countings_bg):
if args == 1:
countings_bg.pack()
ZbrojenieSymetryczne(countings_bg)
class ZbrojenieSymetryczne:
def __init__(self, master):
self.desc_1 = Label(master, text="Wysokość przekroju h [cm]")
self.desc_7 = Label(master, text="Wybór betonu")
self.data_1 = Entry(master, width=6)
var = StringVar()
var.set("Klasa")
self.data_7 = OptionMenu(master, var, "1", "2", command=self.option_menu)
self.data_7.config(width=10)
self.desc_1.grid(row=1, sticky=E)
self.desc_7.grid(row=7, sticky=E)
self.data_1.grid(row=1, column=1)
self.data_7.grid(row=7, column=1, stick="ew")
self.button5 = Button(master, text="Count", command=self.onclick)
self.button5.grid(row=9, columnspan=2, pady=10)
as1, as2 = [0, 0]
self.result_1 = Label(master, text=f"A_s1 = {as1} [cm^2]")
self.result_1.grid(row=12, sticky=E)
self.result_2 = Label(master, text=f"A_s2 = {as2} [cm^2]")
self.result_2.grid(row=13, sticky=E)
def option_menu(self, selection):
self.eta_bet = calculated_value_concrete(selection)
print(self.eta_bet)
def onclick(self):
h = float(self.data_1.get().replace(',', '.')) * 10 ** -2
as1, as2 = function_1(h, self.eta_bet)
self.result_1 = Label(master, text=f"A_s1 = {as1} [cm^2]")
self.result_1.grid(row=12, sticky=E)
self.result_2 = Label(master, text=f"A_s2 = {as2} [cm^2]")
self.result_2.grid(row=13, sticky=E)
root = Tk()
root.title("Obliczanie zbrojenia")
Menu(root)
root.mainloop()
I want the results in the same label as it is in the beginning (under the button)
If you want to update the text of an existing label there are many ways to do this but perhaps consider doing this inside your onclick function rather than creating new buttons.
def onclick(self):
h = float(self.data_1.get().replace(',', '.')) * 10 ** -2
as1, as2 = function_1(h, self.eta_bet)
self.result_1['text'] = f"A_s1 = {as1} [cm^2]"
self.result_2['text'] = f"A_s2 = {as2} [cm^2]"
This should set the text of result_1 and result_2 as per the f-string.
For my coursework i am doing a booking system which uses some tree views. The problem is that if ran from cmd when i double click on a row in the tree view it does not populate the boxes below it, however if i run it from the idle it does. Below is my where i have made my class and two defs which are create_GUI(for first part of gui before double click) and double click(makes second part of GUI)
from tkinter import *
import os
import datetime
import sqlite3
from tkinter.ttk import Combobox,Treeview,Scrollbar
import tkinter as tk
import Utilities
class Application(Frame):
""" Binary to Decimal """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
self.grid()
self.create_GUI()
def Quit(self):
self.master.destroy()
def create_GUI(self):
frame1 = tk.LabelFrame(root, text="frame1", width=300, height=130, bd=5)
frame2 = tk.LabelFrame(root, text="frame2", width=300, height=130, bd=5)
frame1.grid(row=0, column=0, columnspan=3, padx=8)
frame2.grid(row=1, column=0, columnspan=3, padx=8)
self.title_lbl = Label(frame1, text = "Students")
self.title_lbl.grid(row = 0, column = 2)
self.fn_lbl = Label(frame1, text = "First Name:")
self.fn_lbl.grid(row = 1 , column = 1)
self.fn_txt = Entry(frame1)
self.fn_txt.grid(row = 1, column = 2)
self.ln_lbl =Label(frame1, text = "Last Name:")
self.ln_lbl.grid(row = 2, column = 1)
self.ln_txt = Entry(frame1)
self.ln_txt.grid(row = 2, column = 2)
self.q_btn = Button(frame1, text = "Back",padx=80,pady=10, command = lambda: self.Quit())
self.q_btn.grid(row = 3, column = 0)
self.s_btn = Button(frame1, text = "search",padx=80,pady=10, command = lambda: self.search())
self.s_btn.grid(row = 3,column = 3)
self.tree = Treeview(frame2,height = 6)
self.tree["columns"] = ("StudentID","First Name","Last Name")#,"House Number", "Street Name", "Town Or City Name","PostCode","MobilePhoneNumber")
self.tree.column("StudentID",width = 100)
self.tree.column("First Name",width = 100)
self.tree.column("Last Name", width = 100)
## self.tree.column("House Number", width = 60)
## self.tree.column("Street Name", width = 60)
## self.tree.column("Town Or City Name", width = 60)
## self.tree.column("PostCode", width = 60)
## self.tree.column("MobilePhoneNumber", width = 60)
self.tree.heading("StudentID",text="StudentID")
self.tree.heading("First Name",text="First Name")
self.tree.heading("Last Name",text="Last Name")
## self.tree.heading("House Number",text="House Number")
## self.tree.heading("Street Name",text="Street Name")
## self.tree.heading("Town Or City Name",text="Town Or City Name")
## self.tree.heading("PostCode",text="PostCode")
## self.tree.heading("MobilePhoneNumber",text="MobilePhoneNumber")
self.tree["show"] = "headings"
yscrollbar = Scrollbar(frame2, orient='vertical', command=self.tree.yview)
xscrollbar = Scrollbar(frame2, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=yscrollbar.set, xscroll=xscrollbar.set)
yscrollbar.grid(row=1, column=5, padx=2, pady=2, sticky=NS)
self.tree.grid(row=1,column=0,columnspan =5, padx=2,pady=2,sticky =NSEW)
self.tree.bind("<Double-1>",lambda event :self.OnDoubleClick(event))
def OnDoubleClick(self, event):
frame3 = tk.LabelFrame(root, text="frame1", width=300, height=130, bd=5)
frame3.grid(row=2, column=0, columnspan=3, padx=8)
self.message=StringVar()
self.message.set("")
self.lblupdate = Label(frame3, textvariable = self.message).grid(row=0,column=0,sticky=W)
curItem = self.tree.focus()
contents =(self.tree.item(curItem))
StudentDetails = contents['values']
print(StudentDetails)
self.tStudentID=StringVar()
self.tFirstName = StringVar()
self.tLastName = StringVar()
self.tHouseNumber = StringVar()
self.tStreetName = StringVar()
self.tTownOrCityName = StringVar()
self.tPostCode = StringVar()
self.tEmail = StringVar()
self.tMobilePhoneNumber = StringVar()
self.tStudentID.set(StudentDetails[0])
self.tFirstName.set(StudentDetails[1])
self.tLastName.set(StudentDetails[2])
self.tHouseNumber.set(StudentDetails[3])
self.tStreetName.set(StudentDetails[4])
self.tTownOrCityName.set(StudentDetails[5])
self.tPostCode.set(StudentDetails[6])
self.tEmail.set(StudentDetails[7])
self.tMobilePhoneNumber.set(StudentDetails[8])
self.inst_lbl0 = Label(frame3, text = "Student ID").grid(row=5,column=0,sticky=W)
self.StudentID = Label(frame3, textvariable=self.tStudentID).grid(row =5,column=1,stick=W)
self.inst_lbl1 = Label(frame3, text = "First Name").grid(row=6,column=0,sticky=W)
self.NFirstName = Entry(frame3, textvariable=self.tFirstName).grid(row =6,column=1,stick=W)
self.inst_lbl2 = Label(frame3, text = "Last Name").grid(row=7,column=0,sticky=W)
self.NLastName = Entry(frame3, textvariable=self.tLastName).grid(row =7,column=1,stick=W)
self.inst_lbl3 = Label(frame3, text = "House Number").grid(row=8,column=0,sticky=W)
self.HouseNumber = Entry(frame3,textvariable=self.tHouseNumber).grid(row=8,column=1,sticky=W)
self.inst_lbl4 = Label(frame3, text = "Street Name").grid(row=9,column=0,sticky=W)
self.StreetName =Entry(frame3,textvariable=self.tStreetName).grid(row=9,column=1,sticky=W)
self.inst_lbl5 = Label(frame3, text = "Town or City Name").grid(row=10,column=0,sticky=W)
self.TownOrCityName =Entry(frame3,textvariable=self.tTownOrCityName).grid(row=10,column=1,sticky=W)
self.inst_lbl6 = Label(frame3, text = "Postcode").grid(row=11,column=0,sticky=W)
self.PostCode = Entry(frame3,textvariable=self.tPostCode).grid(row=11,column=1,sticky=W)
self.inst_lbl7 = Label(frame3, text = "Email").grid(row=12,column=0,sticky=W)
self.Email =Entry(frame3,textvariable=self.tEmail).grid(row=12,column=1,sticky=W)
self.inst_lbl8 = Label(frame3, text = "Mobile phonenumber").grid(row=13,column=0,sticky=W)
self.MobilePhoneNumber =Entry(frame3,textvariable=self.tMobilePhoneNumber).grid(row=13,column=1,sticky=W)
self.btnSaveChanges = Button(frame3, text = "save changes",padx=80,pady=10,command = lambda:self.SaveChanges()).grid(row=14,column=0,sticky=W)
self.btnSaveChanges = Button(frame3, text = "delete record",padx=80,pady=10,command = lambda:self.DeleteRecord()).grid(row=14,column=1,sticky=W)
def search(self):
FirstName = self.fn_txt.get()
LastName = self.ln_txt.get()
with sqlite3.connect("GuitarLessons.db") as db:
cursor = db.cursor()
cursor.row_factory = sqlite3.Row
sql = "select StudentID,FirstName,LastName,HouseNumber,StreetName,TownOrCityName,PostCode,Email,MobilePhoneNumber"\
" from tblStudents"\
" where FirstName like ?"\
" and LastName like ?"
cursor.execute(sql,("%"+FirstName+"%","%"+LastName+"%",))
StudentList = cursor.fetchall()
print(StudentList)
self.loadStudents(StudentList)
def loadStudents(self,StudentList):
for i in self.tree.get_children():
self.tree.delete(i)
for student in StudentList:
self.tree.insert("" , 0,values=(student[0],student[1],student[2],student[3],student[4],student[5],student[6],student[7],student[8]))
def SaveChanges(self):
valid = True
self.message.set("")
NFirstName = self.tFirstName.get()
NLastName = self.tLastName.get()
NHouseNumber = self.tHouseNumber.get()
NStreetName = self.tStreetName.get()
NTownOrCityName = self.tTownOrCityName.get()
NPostCode = self.tPostCode.get()
NEmail = self.tEmail.get()
NMobilePhoneNumber = self.tMobilePhoneNumber.get()
StudentID = self.tStudentID.get()
if NFirstName == "" or NLastName == "" or NEmail == "" or NMobilePhoneNumber == "":
valid = False
self.message.set('missing details,first name,last name,phone number, email are all needed')
if not Utilities.is_phone_number(NMobilePhoneNumber ):
valid = False
self.message.set('invalid mobile phone number')
if not Utilities.is_postcode(NPostCode):
valid = False
self.message.set('invalid postcode')
if not Utilities.is_email(NEmail):
valid = False
self.message.set('invalid email')
if NHouseNumber != "":
if int(NHouseNumber) < 0:
self.message.set('invalid house number')
if valid == True:
with sqlite3.connect("GuitarLessons.db") as db:
cursor = db.cursor()
sql = "update tblStudents set FirstName =?,LastName=?,HouseNumber=?,StreetName=?,TownOrCityName=?,PostCode=?,Email=?,MobilePhoneNumber=? where StudentID=?"
cursor.execute(sql,(NFirstName,NLastName,NHouseNumber,NStreetName,NTownOrCityName,NPostCode,NEmail,NMobilePhoneNumber,StudentID))
db.commit()
self.message.set("student details updated")
def DeleteRecord(self):
StudentID = self.tStudentID.get()
#StudentID = int(StudentID)
with sqlite3.connect("GuitarLessons.db") as db:
cursor = db.cursor()
sql = "delete from tblStudents where StudentID = ?"
cursor.execute(sql,(StudentID))
db.commit()
self.tlabeupdate.set("student details deleted")
root = Tk()
root.title("booking system")
root.geometry("800x800")
root.configure(bg="white")
app = Application(root)
root.mainloop()
EDIT
when i was copyign and pasting the rest of my code that i forgot to put in the original post i found that it only stops working if i open it through the student menu(separate peice of code) but it works if i dont go through the menu
You must call mainloop() on the root window so that your program can process events.
You create LabelFrames in the parent called root, but root does not exist. To correct it pass master to the function, which receives it as root
class Application():
""" Binary to Decimal """
def __init__(self, master):
""" Initialize the frame. """
self.create_GUI(master)
def create_GUI(self, root):
frame1 = tk.LabelFrame(root, text="frame1", width=300, height=130, bd=5)