Update class instance StringVar() from abstract method - python-2.7

I am trying to update 4 StringVar() with values read only after a file is opened. I'm trying to use an abstract method set_values() on the class TestPage to update the 4 StringVar().
...
class TestPage(Tk.Frame):
def __init__(self, parent, *controller):
Tk.Frame.__init__(self, parent)
self.x = Tk.StringVar()
self.y = Tk.StringVar()
self.z = Tk.StringVar()
self.w = Tk.StringVar()
...
x_label = ttk.Label(self, textvariable=self.x)
y_label = ttk.Label(self, textvariable=self.x)
z_label = ttk.Label(self, textvariable=self.x)
w_label = ttk.Label(self, textvariable=self.x)
...
def set_values(self):
self.x.set(some.list[0])
self.y.set(some.other_list.last_index)
self.z.set(some.list_total_entries)
self.w.set('herro worr')
...
TestPage inherets from Tk.Frame. I believe I 'instantiate' the TestPage object when I call show_frame() in the main Application class, which inherets from Tk:
# ***** Tkinter Gui classes *****
# Main container, called by app.gui.Application() in main.py
class Application(Tk.Tk):
def __init__(self, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
container = Tk.Frame(self, name='container')
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (EntryPage, TestPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(EntryPage)
# ***** Change view/frame *****
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# ***** Open file *****
def open_file(self):
functions.load_file()
...
I would like to call set_values() from my existing load_file function which is in a seperate functions module. I call load_file() to do some populating of graphs, and to parse the file selected for openening.
...
def load_file():
...
if file_name:
gui.TestPage.set_values()
...
...
When I try I get the error:
TypeError: unbound method set_values() must be called with TestPage instance as first argument (got nothing instead)
I need to call the method on the instantiated instance of TestPage, but I do not understand what parameter to supply to set_values() to indicate self or the current instance of TestPage. In the Application class I thought I was instantiating TestPage as frame in the line frame = F(container, self). But I have not been able to reference set_values() using frame either.
I am not even sure this is the best way to do it. I tried to replace the method with binds, events, and also #classmethod and #staticmethod, but with no real succes. Should I be using an abstract method for this?

The values you are changing are attributes of an object, so you need to change them via the instance. In other words, don't pass something to the "self" parameter of a class or abstract function, simply call the function on the object itself.
For example:
...
testfile = TestPage(...)
...
load_file(testpage)
...
def load_file(page):
...
page.set_values()

Related

Python - Overriding a parent variable with a getter/setter

So I have a parent class BaseAdd that I'm trying to subclass. The BaseAdd uses self.left and self.right, I want to use self.nodes to make it easier to access both left and right at once:
class BaseAdd():
def __init__(self, leftright):
self.left = leftright[0]
self.right = leftright[1]
class Add(BaseAdd):
def __init__(self, leftright):
self.nodes = leftright
#property
def left(self):
return self.nodes[0]
#left.setter
def left(self, value):
self.nodes[0] = value
foo = Add(('L', 'R'))
foo.left = "new"
print(foo.left, foo.nodes[0])
>>> ('new', 'L')
The problem is that the setter is never getting called, my hunch is that it's using the BaseAdd.left somehow instead. How can I make the setter properly set the list element?

Write my own keras layer

I want to write my own keras layer with taking as input a tensor with shape (nb_batch, input_dim) and producing a tensor with shape (nb_batch, context_size, output_dim) . I have write a demo below:
class MyLayer(Layer):
def __init__(self, output_dim, context_size, init="uniform", **kwargs):
self.output_dim = output_dim
self.context_size = context_size
self.init = initializations.get(init)
super(MyLayer, self).__init__(**kwargs)
def build(self, input_shape):
input_dim = input_shape[1]
self.W_vec = self.init(
(self.context_size, input_dim, self.output_dim),
name="W_vec")
self.trainable_weights = [self.W_vec]
super(MyLayer, self).build() # be sure you call this somewhere!
def call(self, x, mask=None):
return K.dot(x, self.W_vec)
# return K.dot(x, self.W)
def get_output_shape_for(self, input_shape):
return (input_shape[0], self.context_size, self.output_dim)
when I ran it , got a error "TypeError: build() takes exactly 2 arguments (1 given)"enter code here
Looks like build needs input shape argument
super(MyLayer, self).build(input_shape) # be sure you call this somewhere!

object inheritance arugment input error

Playing around with inheritance and came across an error stating that I am inputing too many arguments. What could I be doing wrong?
This first file is called media.py
class Video():
def __init__(self, title, duration):
self.title = title
self.duration = duration
class Movie(Video):
def __init__(self, movie_story, movie_poster, trailer_youtube):
Video.__init__(self, title, duration)
self.storyline = movie_story
self.poster_image_url = movie_poster
self.trailer_youtube_url = trailer_youtube
def show_trailer(self):
webbrowser.open(self.trailer_youtube_url)
class TvShow(Video):
def __init__(self, season, episode, tv_station):
Video.__init__(self, title, duration)
self.season = season
self.episode = episode
self.tv_station = tv_station
This second file creates the objects.
import fresh_tomatoes
import media
family_guy = media.TvShow("Family Guy",
"2000-Present",
"Fifteen Seasons",
"Twenty-Eight",
"Fox")
print family_guy.title
The terminal output states I'm passing 6 arguments when only 4 may be accepted. Why is that?
Calling the parent __init__ will only invoke it , but you still need to pass in the arguments to it.
So when you invoke __init__ method for TvShow it only expects 3 +1(self) arguments , while you were trying to send more than that. So to solve the issue you just need to increase the number of arguments excepted by the __init__.
class Video():
def __init__(self, title, duration):
self.title = title
self.duration = duration
class Movie(Video):
def __init__(self, movie_story, movie_poster, trailer_youtube):
Video.__init__(self, title, duration)
self.storyline = movie_story
self.poster_image_url = movie_poster
self.trailer_youtube_url = trailer_youtube
def show_trailer(self):
webbrowser.open(self.trailer_youtube_url)
class TvShow(Video):
def __init__(self, season, episode, tv_station, title, duration):
Video.__init__(self, title, duration)
self.season = season
self.episode = episode
self.tv_station = tv_station

How to correctly create a second window in pyqt4

I'm trying to open a second window beside my mainwindow on a button click and display a tablewidget on it with some data. When I open the window it raises
AttributeError: 'Ui_MainWindow' object has no attribute 'openTable'
The mainwindow was created with Qt Designer and converted the ui file with pyuic4. How do I do this correctly correct so that the error is not raised?
The button calls function:
def showCliplist(self):
data = self.metadata_list
luts = self.lutlist
selected_lut = self.LUTBox.currentIndex()
openTable = ClipListViewer(data,luts,selected_lut)
self.openTable.show()
New window class:
class ClipListViewer(QtGui.QWidget):
def __init__(self, data, luts, selected_lut, parent = None):
super(ClipListViewer,self).__init__()
self.setWindowTitle('Cliplist')
self.resize(900,600)
self.metadata = data
self.curentluts = luts
self.choosenlut = selected_lut
y_count = len(self.metadata)
self.table = QtGui.QTableWidget(y_count,6)
self.table.setHorizontalHeaderLabels(['Clip', 'Videocodec', 'FPS', 'Audiocodec', 'Start Timecode', 'LUT'])
x = y = 0
for items in self.metadata:
for entry in items:
#print entry
self.table.setItem(y, x, QtGui.QTableWidgetItem(entry))
self.table.resizeColumnToContents(x)
x += 1
self.comb = QtGui.QComboBox()
for lutname in self.curentluts:
self.comb.addItem(lutname)
self.comb.setCurrentIndex(self.choosenlut)
self.table.setCellWidget(y, 5, self.comb)
self.table.setColumnWidth(5, 230)
y += 1
x = 0
self.table.resizeRowsToContents()
layout = QtGui.QHBoxLayout()
layout.addWidget(self.table)
self.setLayout(layout)
self.show()
def closeEvent(self, event): #check if window was closed
print "Cliplist Window was closed! "
I reviews your code completed, OK, let's me explain.
AttributeError: 'Ui_MainWindow' object has no attribute 'openTable'
This error says, "I not have self.openTable in class Ui_MainWindow (That true because your have create own method)".
Why ? : Because a problem is in line this;
def showCliplist(self):
data = self.metadata_list
luts = self.lutlist
selected_lut = self.LUTBox.currentIndex()
openTable = ClipListViewer(data,luts,selected_lut) # <- (1) THIS LINE
self.openTable.show() # <- (2) THIS LINE
In (1), your create your second widget in to openTable (Not self.openTable).
This line we have this object in openTable (Not self.openTable).
Then (2), your call QtGui.QWidget.show(self) to show widget of self.openTable (Not openTable). It's should be error because we don't have variable self.openTable. To fix it your should use same name variable, Like this;
def showCliplist(self):
data = self.metadata_list
luts = self.lutlist
selected_lut = self.LUTBox.currentIndex()
self.openTable = ClipListViewer(data,luts,selected_lut) # <- FIX THIS LINE !
self.openTable.show() # <- (2) THIS LINE
Why second widget is show before I call self.openTable.show()?
Answer : Your can see in second widget initiate in last line of code your see QtGui.QWidget.show(self) has be call before end of initiate;
class ClipListViewer(QtGui.QWidget):
def __init__(self, data, luts, selected_lut, parent = None):
super(ClipListViewer,self).__init__()
.
.
.
self.show() # <- THIS LINE
Regards,

How to mass produce entry box widgets in Tkinter?

I would like to turn the following 4 lines of code into 1 line by calling a function or class. This way, i can just call the function for each entry box widget i want to create:
self.systest = StringVar()
self.systest.set("N/A")
self.e = Entry(self.frame1, textvariable=self.systest)
self.e.grid(row=6, column=1)
here is the function i am trying to create (doesn't actually work):
def entry_boxes(self, row, col, default, var, frame):
setattr(self, var, StringVar)
setattr(self, var, default)
e = Entry(frame, textvariable=var)
e.grid(row=row, column=col)
calling it:
entry_boxes(self,6,1,'N/A','self.systest',self.frame1)
This will be part of a class, so i need the variables to be callable from anywhere in it.
Are you trying something like this?
from Tkinter import StringVar,Entry,Tk
class UIclass():
def __init__(self,root):
#define self.frame1
self.myfunc()
def myfunc(self):
self.entry_boxes(6,1,'N/A','self.systest',self.frame1)
self.entry_boxes(6,2,'N/A','self.systest',self.frame1)
...
...
...
def entry_boxes(self, row, col, default, var, frame):
setattr(self, var, StringVar)
setattr(self, var, default)
e = Entry(frame, textvariable=var)
e.grid(row=row, column=col)
if __name__ == '__main__':
root = Tk()
UIclass(root)
root.mainloop()
If not,kindly do tell me so that I can delete this answer