From where comes the parent argument (PySide)? - python

In this example, from where comes the parent argument, who provides it?
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.do_something() #sanity check
self.cw = ChildWidget(self)
self.setCentralWidget(self.cw)
self.show()
def do_something(self):
print 'doing something!'
class ChildWidget(QtGui.QWidget):
def __init__(self, parent):
super(ChildWidget, self).__init__(parent)
self.button1 = QtGui.QPushButton()
self.button1.clicked.connect(self.do_something_else)
self.button2 = QtGui.QPushButton()
self.button2.clicked.connect(self.parent().do_something)
self.layout = QtGui.QVBoxLayout()
self.layout.addWidget(self.button1)
self.layout.addWidget(self.button2)
self.setLayout(self.layout)
self.show()
def do_something_else(self):
print 'doing something else!'

Parent and children are specific to Qt (C++). From the doc of QObject:
QObjects organize themselves in object trees. When you create a
QObject with another object as parent, the object will automatically
add itself to the parent's children() list. The parent takes ownership
of the object; i.e., it will automatically delete its children in its
destructor.
QWidget and a lot of other class inherits fromQObject, so it apply to them too. For every children, the parent() method returns a pointer to the parent object.
Basically, your creates widget with parents so they can be deleted properly.
Common case, your main window is the parent - or grandparent - of all your widgets: when you close the window, everything is deleted in the right order.
From your comment, I think your also confused with the use ofsuper(). It does not call the parent of the widget.
Another way to write this:
class ChildWidget(QtGui.QWidget):
def __init__(self, parent):
super(ChildWidget, self).__init__(parent)
is to call the init method of QWidget directly:
class ChildWidget(QtGui.QWidget):
def __init__(self, parent):
QtGui.QWidget.__init__(parent)
ChildWidget inherits from QWidget (that's how we defined the class). In the init method, you need to call the default constructor of QWidget. Otherwise you won't be able to use the default methods and attributes of QWidget (try and see...).
If given a parent, it will also organize itself accordingly. It will add itself to the parent children method, and keep a reference to its parent.

Related

How to bind a function to an Action from Qt menubar?

I'm using Python3 and PyQt5, make my widgets and windows in Qt Designer. What is more, I do not generate .py files from a .ui. I simply load it using next code:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
So, I wanted to know, how do I bind menu bar actions to functions.
Is there any way I can do something like this?
self.getActionByName("actionTest_Action").connect(self.do_something)
It is not necessary to use findChild when using loadUi since this method adds the object to the attributes of the class using the objectName as a name, for example in this particular case a cleaner code than the other answer is:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
self.actionTest_Action.triggered.connect(self.test)
def test(self):
print("Test")
So, answering my own question..
One way to do this, is to find an action by using FindChild(QAction, "ActionName") function, and then bind a function using connect() function
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
action = self.findChild(QAction, "actionTest_Action")
action.triggered.connect(self.test)
def test(self):
print("Test")

How to hide a window in the constructor immediately after creation?

I want to hide a window immediately after it is created. It works only if I do this with the help of button or something.
class Example(QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.hide() # doesn't work
self.btn = QPushButton('Hide', self)
self.btn.clicked.connect(self.click) # works
self.btn.show()
def click(self): # works
self.hide()
Apparently it seems that the code should work. What may be happening is that you are calling show() after creating the object. For example:
example = Example()
example.show()
Read this answer about hide() and show(): What's the difference in Qt between setVisible, setShown and show/hide
You can use QtCore.QTimer
class Example(QWidget):
def __init__(self, app):
QWidget.__init__(self)
QTimer.singleShot(0, self.hide)

what is the best way to embed program logic that seats in some algorithm class into pyqt4 user interface

class SomNetwork(object):
def __init__(self, dataset):
# some parameters that are not important here
pass
def one_step_learn(self, k, sigma_0, gamma_0, alfa, mcolor,population_of_ids):
pass
def learn(self):
pass
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_QSom()
self.ui.setupUi(self)
self.frame = MyFrame(self)
self.setCentralWidget(self.frame)
self.frame.start()
self.show()
class MyFrame(QtGui.QFrame):
simulationSpeed = 5000
def __init__(self, parent):
super(Ramka, self).__init__(parent)
self.init_Board()
def init_Board(self):
self.timer = QtCore.QBasicTimer()
I would like to be able to interact with SomNetwork class in order to be able to call its methods from within inside of the MyFrame class methods. Are there any special design patterns that would suit this example the most or should I just add instance of the class as a field to the MyFrame class.
Thanks of your help in advance!
I don't know if your question is heading towards this, but for your network you could try to subclass a QtCore.QObject instead. On the whole you should instance your network as a member of your QMainWindow, so your frame and the net can interact via signals and slots.
... By the way, there is a little flaw in your code, when you call the constructor of a QWidget in the subclass of a QMainWindow.

Override or remove an object from __init__ parent class from child's class

Currently, I have two classes:
class Parent:
def __init__(self, controller, parent):
# Key press event bind 'Return Key'
self.controller.bind('<Return>', self.averageTesting)
def averageTesting(variable):
if len(variable) > 0:
return variable
else:
messagebox.showerror("Error", "Enter a valid variable")
class Child(Parent):
def __init__(self):
......
The parent class is actually page one and child class is page two of the Tkinter frame pages.
I don't want the child to have the messagebox showing. Right now when I go to page two or the child class and I press return on my keyboard, the message shows up. And I don't want that in the second page. Only the first page which is the parent class.
But I need to inherit everything but the messagebox from the parent class to the child class.
How do I do achieve this?
Personally, I think that if you must exclude parts of your parent's constructor then your design is flawed. You could instead make the parent class more generic and make your current parent and your current child both inherit from the new parent.
If you really want to stick with that pattern then you could just unbind the event. If this is the only callback connected to the event then you can just do.
x = Child()
x.controller.unbind('<Return>')
Edit:
My next suggestion is to instead move the binding to a separate method inside the parent class. For example.
class Parent:
def __init__(self, controller, parent):
self.controller = controller
...
def averageTesting(variable):
if len(variable) > 0:
return variable
else:
messagebox.showerror("Error", "Enter a valid variable")
def initializeBinding(self):
self.controller.bind('<Return>', self.averageTesting)
... # plus anymore bindings that only the parent must have
class Child(Parent):
def __init__(self):
...
So now when you want to use the parent you would do this.
p = Parent(...)
p.initializeBinding()
Whereas when you instantiate a Child object you don't call the method.

Menus and toolbar

I am new in programming and I have created a simple application with one class in Python and PySide which manipulates phone bill csv files. Now I want an option for mobile too.
How can I add a menubar, when my class inherits from QWidget? Should I write another class which inherits from QMainWindow and then make an instance of my first class as a central widget? Is this the right way to do this?
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
....
class MyWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
widget = MyWidget()
self.setCentralWidget(widget)
...
There's no need for a QMainWindow, you can simply create a QMenuBar in your widget.
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.menu=QtGui.QMenuBar()
self.menu.addAction("do something")
layout=QtGui.QVBoxLayout()
layout.addWidget(self.menu)
A QMainWindow is basically a widget which already has a layout with a menu bar, a toolbar, a status bar, etc. If you don't need all of those functionality, you can use a simple QWidget and add only what you want.

Categories

Resources