Class Struggle: Connecting a Method to an Outside Variable - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html) +--- Thread: Class Struggle: Connecting a Method to an Outside Variable (/thread-7698.html) |
Class Struggle: Connecting a Method to an Outside Variable - vulpesVelox - Jan-21-2018 First off, be warned: I am a hopeless newbie within the realms of python with just shy of two months of experience thus far. I am making slow progress, however, and normally I can manage working out the bugs and assorted snags if I just put a little work into researching. In this case, however, I'm somewhat stuck as I cannot wrap my head around what would otherwise appear to be a simple operation. During the past week it has grown into some variation of 'code blindness'; the further I've been digging, the worse the code has gotten*, so now I turn to you, the good people of python-forum. I would like to somehow connect 'myVar' to 'button_1', 'button_2' and 'button_3' in the method shown below. I've made a v1.0 of the program (a weather station that scrapes the web for a forecast and assorted data) which works witout using classes, but then I thought that it would be a good exercise to implement classes. Oh, Icarus. I've omitted the rest of the code as I don't think it bears relevance, but will upload the entire script if needed, of course; just let me know, please. Thank you for taking the time to read through this post :) from tkinter import * class lbl(object): def __init__(self, pos, txt, row, col, colspan): self.position = pos self.text = txt self.row = row self.column = col self.columnspan = colspan myVar = Label(self.position, self.text) myVar.grid(self.row, self.column, self.columnspan) root = Tk() root.title("Vejrstation 1.0") root.geometry("350x350") #root.resizable(True, True) root.resizable(False, False) label_1 = lbl(root, "temp.", 0, 0, 1) label_2 = lbl(root, "fugt", 0, 1, 1) label_3 = lbl(root, "vind", 0, 2, 1) root.mainloop()* I would supply some of my more horrendous attempts and ideas for the shere comedy value, but let's keep it concise for now, eh? ;) RE: Class Struggle: Connecting a Method to an Outside Variable - Gribouillis - Jan-21-2018 (Jan-21-2018, 06:40 PM)vulpesVelox Wrote: I would like to somehow connect 'myVar' to 'button_1', 'button_2' and 'button_3' in the method shown below.You want the bind() method:myVar.bind('Button-1', myMethod) RE: Class Struggle: Connecting a Method to an Outside Variable - vulpesVelox - Jan-22-2018 (Jan-21-2018, 09:07 PM)Gribouillis Wrote: You want theI've tried to insert your suggestion in a couple of different ways now, but all attempts result in either: NameError: name 'myVar' is not defined or: NameError: name 'label_1' is not defined I did a bit of reading on the subject, and it turns out that 'Button-1' is a fixed expression within the realm of the bind method, hence it wont bind to a label or a text field or any object which is not a button in tkinter. - Right? Thank you all the same; now I know there's a method called bind. Any type of progress is good progress :) For clarity, here's version 1 (without using classes). This one works just fine. from tkinter import * import requests from bs4 import BeautifulSoup import re #-------------------------------# # - request module - Forecast - # #-------------------------------# data1 = requests.get('https://www.dmi.dk/vejr/til-lands/byvejr/by/vis/DK/1000/K%C3%B8benhavn,%20Danmark/') soup = BeautifulSoup(data1.text, 'html.parser') #print(soup) data2 = soup.find('div',{'id':'NJ'}) #print(data2) data3 = data2.find_all('p') #print(data3) data4 = data3[2] #-------------------------------# # - request modules - # #-------------------------------# blabla = requests.get('https://www.dmi.dk/vejr/til-lands/regionaludsigten/kbhnsjaelland/') toast = BeautifulSoup(blabla.text, 'html.parser') #print(toast) bleble = toast.find('div', {'id':'c5886'}) #print(bleble) blibli = bleble.find_all('td') #print(blibli) #temp bloblo = blibli[2] #print(bloblo.string[0:6]) #fugt blublu = blibli[3] #print(blublu.string[0:5]) #vind blybly = blibli[5] #print(blybly.string[0:5]) #solopgang blaxblax = toast.find('div', {'id':'c3065'}) #print(blaxblax) blexblex = blaxblax.find_all('p') #print(blexblex) blixblix = str(blexblex[2]) #print(blixblix) #print(type(blixblix)) bloxblox = re.search('solnedgang: ', blixblix) #print(str(bloxblox)) start = bloxblox.end() end = start + 10 #print(blixblix[start:end]) #-------------------------------# # - tkinter window - # #-------------------------------# root = Tk() root.title("Vejrstation 1.0") root.geometry("350x360") root.resizable(False, False) #root.resizable(False, False) #-------------------------------# # - button funcs - # #-------------------------------# def butt1_func(): print("it's alive.") def butt2_func(): print("This one is also alive.") def butt3_func(): quit() #-------------------------------# # - labels, buttons and text - # #-------------------------------# """smølfe om til classes, måske?""" label_1 = Label(root, text="Temp.") label_1.grid(row=0, column=0) label_1 = Label(root, text="Fugt.") label_1.grid(row=0, column=1) label_1 = Label(root, text="Vind") label_1.grid(row=0, column=2) textbox_1 = Text(root, height=1,width=10) textbox_1.grid(row=1, column=0) textbox_1.insert(END, bloblo.string[0:6]) textbox_1 = Text(root, height=1,width=10) textbox_1.grid(row=1, column=1) textbox_1.insert(END, blublu.string[0:5]) textbox_1 = Text(root, height=1,width=10) textbox_1.grid(row=1, column=2) textbox_1.insert(END, blybly.string[0:6]) #spacer spacer = Label(root) spacer.grid(row=2) label_3 = Label(root, text="Solopgang/solnedgang") label_3.grid(row=3, column=0, columnspan=1) textbox_3 = Text(root, height=1, width=10) textbox_3.grid(row=4, column=0, columnspan=1) textbox_3.insert(END, blixblix[start:end]) #spacer spacer = Label(root) spacer.grid(row=5) label_2 = Label(root, text="DMI Vejrudsigt") label_2.grid(row=6, column=0, columnspan=3) Scroller = Scrollbar(root) textbox_2 = Text(root, height=10, width=49, wrap=WORD) Scroller.grid(row=7, column=0) textbox_2.grid(row=7, column=0, columnspan=3) Scroller.config(command=textbox_2.yview) textbox_2.config(yscrollcommand=Scroller.set) textbox_2.insert(END, data4.string) #spacer spacer = Label(root) spacer.grid(row=8) label_2 = Label(root, text="Nogle forskellige knapper") label_2.grid(row=9, column=0, columnspan=3) button_1 = Button(root, text="SEND!", command=butt1_func) button_1.grid(row=10, column=0, sticky="NWNESWSE") button_2 = Button(root, text="ASSIGN!", command=butt2_func) button_2.grid(row=10, column=1, sticky="NWNESWSE") button_3 = Button(root, text="ABORT!", command=butt3_func) button_3.grid(row=10, column=2, sticky="NWNESWSE") #-------------------------------# # - run that sucka! - # #-------------------------------# root.mainloop()And here's version 2 in which I would like to create classes for the elements involved (doesn't work; computer says nooooo!): from tkinter import * import requests from bs4 import BeautifulSoup import re #-------------------------------# # - request module - Forecast - # #-------------------------------# data1 = requests.get('https://www.dmi.dk/vejr/til-lands/byvejr/by/vis/DK/1000/K%C3%B8benhavn,%20Danmark/') soup = BeautifulSoup(data1.text, 'html.parser') #print(soup) data2 = soup.find('div',{'id':'NJ'}) #print(data2) data3 = data2.find_all('p') #print(data3) data4 = data3[2] #-------------------------------# # - other request modules - # #-------------------------------# blabla = requests.get('https://www.dmi.dk/vejr/til-lands/regionaludsigten/kbhnsjaelland/') toast = BeautifulSoup(blabla.text, 'html.parser') #print(toast) bleble = toast.find('div', {'id':'c5886'}) #print(bleble) blibli = bleble.find_all('td') #print(blibli) #temp bloblo = blibli[2] #print(bloblo.string[0:6]) #fugt blublu = blibli[3] #print(blublu.string[0:5]) #vind blybly = blibli[5] #print(blybly.string[0:5]) #solopgang blaxblax = toast.find('div', {'id':'c3065'}) #print(blaxblax) blexblex = blaxblax.find_all('p') #print(blexblex) blixblix = str(blexblex[2]) #print(blixblix) #print(type(blixblix)) bloxblox = re.search('solnedgang: ', blixblix) #print(str(bloxblox)) start = bloxblox.end() end = start + 10 #print(blixblix[start:end]) #-------------------------------# # - tkinter window - # #-------------------------------# root = Tk() root.title("Vejrstation 1.0") root.geometry("350x350") #root.resizable(True, True) root.resizable(False, False) #-------------------------------# # - button funcs - # #-------------------------------# def butt1_func(): print("it's alive.") def butt2_func(): print("This one is also alive.") def butt3_func(): quit() #-------------------------------# # - classes - # #-------------------------------# class lbl(object): def __init__(self, pos, txt, row, col, colspan): self.position = pos self.text = txt self.row = row self.column = col self.columnspan = colspan myVar = Label(self.position, self.text) myVar.grid(self.row, self.column, self.columnspan) class spcr(object): def __init__(self, pos, row, col, colspan): self.position = pos self.row = row self.column = col self.columnspan = colspan myVar = Label(self.position) myVar.grid(self.row, self.column, self.columnspan) class txtbox(object): def __init(self, pos, height, width, wrap, txt, row, col, colspan): self.position = pos self.height = height self.width = width self.text = txt self.row = row self.column = col self.columnspan = colspan self.wrap = wrap myVar = Text(self.position, self.height, self.width, self.wrap) myVar.grid(self.row, self.column, self.columnspan) myVar.insert(END, self.text) class btn(object): def __init__(self, pos, txt, cmd, row, col, colspan, sticky): self.position = pos self.text = txt self.command = cmd self.row = row self.column = col self.columnspan = colspan self.sticky = sticky myVar = Button(self.position, self.text, self.cmd) myVar.grid(self.row, self.column, self.columnspan, self.sticky) label_1 = lbl(root, "temp.", 0, 0, 1) label_2 = lbl(root, "fugt", 0, 1, 1) label_3 = lbl(root, "vind", 0, 2, 1) textbox_1 = txtbox(root, 1, 10, None, 1, 0, 1) textbox_2 = txtbox(root, 1, 10, None, 1, 1, 1) textbox_3 = txtbox(root, 1, 10, None, 1, 2, 1) spacer_1 = spcr(root, 2, 0, 3) label_4 = lbl(root, "solopgang/solnedgang", 3, 0, 1) textbox_4 = txtbox(root, 1, 10, None, 4, 0, 1) spacer_2 = spcr(root, 5, 0, 3) label_5 = lbl(root, "DMI vejrudsigt", 6, 0, 3) textbox_5 = txtbox(root, 10, 49, None, 7, 0, 3) spacer_3 = spcr(root, 8, 0, 3) label_6 = lbl(root, "Nogle forskellige knapper", 9, 0, 3) button_1 = btn(root, "TRANSMIT!", butt1_func, 10, 0, 1, "NWNESWSE") button_2 = btn(root, "UPDATE!", butt2_func, 10, 1, 1, "NWNESWSE") button_3 = btn(root, "ABORT!", butt3_func, 10, 2, 1, "NWNESWSE") #-------------------------------# # - run that sucka! - # #-------------------------------# root.mainloop() RE: Class Struggle: Connecting a Method to an Outside Variable - Gribouillis - Jan-23-2018 I'm not sure it's a good idea to remove the explicit keywords when calling tkinter's methods, because the order of the arguments may be incorrect. Also you may need to keep a reference to the object you created in the init method, for example class btn(object): def __init__(self, pos, txt, cmd, row, col, colspan, sticky): self.position = pos self.text = txt self.command = cmd self.row = row self.column = col self.columnspan = colspan self.sticky = sticky self.myVar = Button(self.position, text=self.text, command=self.cmd) self.myVar.grid(row=self.row, column=self.column, columnspan=self.columnspan, sticky=self.sticky)Concerning myVar.bind('Button-1', myMethod) , this call binds the event 'Button-1' , which is the left mouse button event to the method myMethod for the tkinter widget myVar . Of course you can use this call only if there are a widget and a method named myVar and myMethod in the scope of the call.
RE: Class Struggle: Connecting a Method to an Outside Variable - Larz60+ - Jan-23-2018 using myVar as a name for a widget is misleading. the textvariable attribute should point to a tk.StringVar which you can preset using that attribute and a tk.StringVar. The StringVar can be set externally with string_var_name.set() (replace string_var_name with actual name) It can be initally be set within the button definition string_var_name = StringVar() self.myVar = Button(self.position, text=self.text, textvariable=string_var_name, command=self.cmd)Again, rename myVar to a meaningful widget name. Also to be in conformance with PEP8, don't use camel case, use underscore instead see: http://effbot.org/tkinterbook/variable.htm Sorry for the edits, just got up RE: Class Struggle: Connecting a Method to an Outside Variable - vulpesVelox - Jan-23-2018 (Jan-23-2018, 06:52 AM)Gribouillis Wrote: I'm not sure it's a good idea to remove the explicit keywords when calling tkinter's methods, because the order of the arguments may be incorrect. Also you may need to keep a reference to the object you created in the init method, for example The explicit order of the args is addressed via the grid args, isn't it? Am I to understand that version 1 is more correct than version 2? (Jan-23-2018, 10:53 AM)Larz60+ Wrote: using myVar as a name for a widget is misleading. Going through PEP8 documentation and getting all those things right is a 2nd priority for the time being. It wouldn't make much sense sifting through that information if you basically don't know how to write code; sort of like learning grammar theory without knowing how to read/spell. It is in the post, however, and I do understand what you're trying to convey. And I'm trying to adhere whilst unlearning/modifying what I know from ActionScript. "myVar" doesn't belong. I think. It's there for lack of an alternative method (what I'm looking for), but we could call it whatever you would prefer as far as I'm concerned. "myString", "myTempWord", "Knudpovlsen" or even "Giraffe". RE: Class Struggle: Connecting a Method to an Outside Variable - Gribouillis - Jan-23-2018 (Jan-23-2018, 03:18 PM)vulpesVelox Wrote: The explicit order of the args is addressed via the grid args, isn't it?The signature of the grid method is >>> inspect.signature(tkinter.Button.grid) <Signature (self, cnf={}, **kw)>The documentation doesn't suggest a particular order for the arguments, so yes the keywords are needed. (Jan-23-2018, 03:18 PM)vulpesVelox Wrote: "myVar" doesn't belong. I think. It's there for lack of an alternative methodI think myVar is indeed misleading in a tkinter program if the value is not a tkinter variable.
RE: Class Struggle: Connecting a Method to an Outside Variable - vulpesVelox - Jan-27-2018 I had my mate go over it with me, and the conclusion is, that it would probably be more effective if I let it go for now and focus on learning different things. Thank you all the same, gentlemen, very kind of you :) |