Python 2 Inheriting from calling class and another specified class - python-2.7

Here is my setup. This isn't all the code, just the important parts
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
class MyToolbar(NavigationToolbar):
def __init__(self, figure_canvas, parent, main):
self.toolitems = (
('Home', 'Reset Original View', 'home', 'home'), # (Title, Tooltip, Icon, callback function)
('Back', 'Back to previous view', 'back', 'back'),
('Forward', 'Forward to next view', 'forward', 'forward'),
('Clear', 'Clear all graphs', 'clearIcon', 'on_click_clear_graph'),
)
NavigationToolbar.__init__(self, figure_canvas, parent)
def on_click_clear_graph(self):
# I need to access calling class' (PlotWindow's) clearAx method here
super(MyToolbar,self).clearAx() # but this doesn't work
class PlotWindow():
def __init__(self):
self.figure = Figure()
self.ax = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.figure)
self.toolbar = MyToolbar(self.canvas, self, parent)
def clearAX(self):
self.ax.clear()
I use the MyToolbar class to add extra tools to the Matplotlib toolbar, but I also need to get access to the variables in the PlotWindow class.
I have been using super() in other parts of the program and I can use it to get access to parent classes but in this case I cannot seem to get it to work.
Am I missing some part of it?
Perhaps if the above code doesn't make sense this example below could be used.
class A(SomeOtherInheritedClass):
# how can I call print_something from class B here
# without interfering with SomeOtherInheritedClass
class B():
a = A()
def print_something(self):
print "something"

Related

Print Message in Text Widget that is part of a class

I am fairly new to object-oriented programming. I have a class called MessageWindow which generates a Tkinter text widget inside of a Frame. In my main function I want to write a message into the text widget but when I run the program I get: Class MessageWindow has no attribute text1
I've tried following other responses here on Stack overflow, and another tutorial on the web and I always end up back at the same error
from Tkinter import *
class MessageWindow(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack(fill='both', expand='yes')
self.text1 =Text(self,height=9, width=13)
self.text1.pack()
def main():
root=Tk()
root.title("MessageWindow")
app = MessageWindow(root)
root.mainloop()
MessageWindow.text1.insert(END,"This is a test Message")
MessageWindow.text1.pack()
if __name__=='__main__':
main()
Any help would be appreciated. I need to understand this for a larger GUI project that I am working on.
Ok so
1. You are referring to MessageWindow as your class object when you should be referring to app, as you have instantiated the class as 'app' in your main definition.
2. Your root.mainloop() should be after all your GUI code as it will not take affect if it is after/outisde the mainloop.
So this is the How the code is supposed to be:
from Tkinter import *
class MessageWindow(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack(fill='both', expand='yes')
self.text1 = Text(self,height=9, width=13)
self.text1.pack()
def main():
root=Tk()
root.title("MessageWindow")
app = MessageWindow(root)
# Fix one
app.text1.insert(END,"This is a test Message")
app.text1.pack()
# Fix two
root.mainloop()
if __name__=='__main__':
main()

Python 3 Tkinter - How to call a function from another class

I am trying to get my save button to call a function from another class. I would like to click on the save button as much as I want and it should print "hello people" every time. Though, I am having trouble in getting the save button to work.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.createWidgets()
def createWidgets(self):
#save button
self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
#When I click the button save, I would like it to call the test function in the documentMaker class
self.saveButton = tk.Button(self.parent, text = "Save", command = documentMaker.test(self))
self.saveButton.pack()
class documentMaker():
def test(self):
print ("hello people")
root = tk.Tk()
app = Application(root)
app.master.title('Sample application')
object = documentMaker()
object.test()
app.mainloop()
In your documentMaker class, change the test method to a #staticmethod:
class documentMaker():
#staticmethod
def test(cls):
print ("hello people")
Then your saveButton's command can be:
command = documentMaker.test
A staticmethod is bound to the class, not to an instance of the class like an instance method. So, we can call it from the class's name directly. If you did not want it to be a staticmethod, you could keep it an instance method and have the command line change to:
command = documentMaker().test

PyQt 4: Get Position of Toolbar

Hy guys,
in my executable program there is a toolbar. Well, the user decides to move the toolbar. Now the toolbar is floating. I know I have to conntect the floating-signals that is emittted when the toolbar ist arranged by the user. How can I save the new position of the toolbar? I know the method of adding the toolbar to the main window with a position:self.addToolBar( Qt.LeftToolBarArea , toolbar_name). In the handle_floating()-method you see what I want: There I want to get the position currently, but how? You also see I have just added one member variable, named self.toolbar_pos, to hold the position of the toolbar. My idea is, when application is terminated I want to serialize this value to a file, and later, when application is ran again its will read that file and set the toolbar accordingly. But this is no problem. Currently I don't have no idea to get the position of the toolbar.
I need your help :)
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.toolbar_pos = None
self.initUI()
def initUI(self):
exitAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.triggered.connect(QtGui.qApp.quit)
self.toolbar = QtGui.QToolBar(self)
self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.addToolBar(self.toolbar )
self.toolbar.addAction(exitAction)
self.toolbar.setAllowedAreas(QtCore.Qt.TopToolBarArea
| QtCore.Qt.BottomToolBarArea
| QtCore.Qt.LeftToolBarArea
| QtCore.Qt.RightToolBarArea)
self.addToolBar( QtCore.Qt.LeftToolBarArea , self.toolbar )
self.toolbar.topLevelChanged.connect(self.handle_floating)
def handle_floating(self, event):
# The topLevel parameter is true
# if the toolbar is now floating
if not event:
# If the toolbar no longer floats,
# then calculate the position where the
# toolbar is located currently.
self.toolbar_pos = None
print "Get position: ?"
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.setGeometry(300, 300, 300, 200)
ex.setWindowTitle('Toolbar example')
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The QMainWindow class already has APIs for this: i.e. saveState and restoreState. These can be used to save and restore the state of all the toolbars and dock-widgets in your application.
To use them, you first need to make sure that all your toolbars and dock-widgets are given a unique object-name when they are created:
class Example(QtGui.QMainWindow):
...
def initUI(self):
...
self.toolbar = QtGui.QToolBar(self)
self.toolbar.setObjectName('foobar')
Then you can override closeEvent to save the state:
class Example(QtGui.QMainWindow):
...
def closeEvent(self, event):
with open('/tmp/test.conf', 'wb') as stream:
stream.write(self.saveState().data())
(NB: I've just used a temporary file here for testing, but it would obviously be much better to use something like QSettings in your real application).
Finally, you can restore the state that was saved previously:
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
...
self.initUI()
try:
with open('/tmp/test.conf', 'rb') as stream:
self.restoreState(QtCore.QByteArray(stream.read()))
except IOError:
pass

Maya + PyQt dialog. How to run a single copy of Qt window?

use this simple code for run a window based on qdialog:
import maya.OpenMayaUI as mui
import sip
from PyQt4 import QtGui, QtCore, uic
#----------------------------------------------------------------------
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QtCore.QObject)
#----------------------------------------------------------------------
form_class, base_class = uic.loadUiType('perforceBrowserWnd.ui')
#----------------------------------------------------------------------
class PerforceWindow(base_class, form_class):
def __init__(self, parent=getMayaWindow()):
super(base_class, self).__init__(parent)
self.setupUi(self)
#----------------------------------------------------------------------
def perforceBrowser2():
perforceBrowserWnd = PerforceWindow()
perforceBrowserWnd.show()
perforceBrowser2()
every time you run the function perforceBrowser2() there is a new copy of windows.
how to find whether a window is already running and not to open a new copy of it, and go to the opened window? or just do not give a script to run a second copy of window?
ps. maya2014 + pyqt4 + python2.7
Keep a global reference to the window:
perforceBrowserWnd = None
def perforceBrowser2():
global perforceBrowserWnd
if perforceBrowserWnd is None:
perforceBrowserWnd = PerforceWindow()
perforceBrowserWnd.show()
Using global's are not the preferred way and there are ton's of articles why it is a bad idea.
Why are global variables evil?
It is cleaner to remember the instance in a static var of the class and whenever you load the UI, check if it does already exist and return it, if not create it. (There is a pattern called Singleton that describes this behaviour as well)
import sys
from Qt import QtGui, QtWidgets, QtCore
class Foo(QtWidgets.QDialog):
instance = None
def __init__(self, parent=None):
super(Foo, self).__init__(parent)
self.setWindowTitle('Test')
def loadUI():
if not Foo.instance:
Foo.instance = Foo()
Foo.instance.show()
Foo.instance.raise_()
loadUI()
Whenever you call loadUI it will return the same UI and will not recreate each time you call it.

Flask-WTF and field name

I'd like to change name attribure of SubmitField (which is "submit" by default). What have I tried:
from flask.ext.wtf import Form, SubmitField
class BaseForm(Form):
submit = SubmitField('Create', id='submit_button', name='submit_button') #1
submit = SubmitField('Create', id='submit_button', _name='submit_button') #2
def __init__(self, edit=None, *args, **kwargs):
self.submit.kwargs['name'] = 'submit_button' #5
self.submit.kwargs['_name'] = 'submit_button' #6
All of them failed with different error. If I removing name or _name parameter all working fine. I found that name attribute is passed by flask.ext.wtf.Form but I have no sense how to fix it.
NOTE: I am using not trivial import of my form: it is imported in run-time, inside of view's method, not at the top of file. I cannot and will not change it because of technical issues. I.e. if I copy-pasting my code in IDLE it is working ok. But if I importing this code inside port method of MethodView it is fails.
The simplest way to change the name is to change the name of the field:
class BaseForm(Form):
# This one's name will be submit_button
submit_button = SubmitField('Create')
# This one's name will be another_button
another_button = SubmitField('Do Stuff')
Have you looked at extending the SubmitField itself with a custom constructor. See an example here
Basically you would do something like:
class CustomSubmitField(SubmitField):
def __init__(self, label='', validators=None,_name='',**kwargs):
super(SubmitField, self).__init__(label, validators, **kwargs)
custom_name = "whatever"
self._name = custom_name