The main window is declared in Class1. I am trying to create an object of Class2, create a widget( a push button) and connect it to a slot.
import sys
from PyQt4 import QtGui,QtCore
class Class2(object):
def __init__(self,parent):
return
def button(self,parent):
self.print_button=QtGui.QPushButton("print hello",parent)
self.print_button.show()
self.print_button.clicked.connect(self.print_hello)
def print_hello(self,parent):
print 'hello'
class Class1(QtGui.QMainWindow):
def __init__(self):
super(Class1, self).__init__()
self.welcomeScreen()
def welcomeScreen(self):
obj=Class2(self)
obj.button(self)
def main():
app = QtGui.QApplication(sys.argv)
mw = Class1()
mw.show()
sys.exit(app.exec_())
if __name__=='__main__':
main()
Now, the button is getting created but the slot is not working. How to deal with this problem?
Your print_hello takes 2 arguments, and you pass it only a one.
Try this:
self.print_button.clicked.connect(lambda: self.print_hello(self))
Related
I am creating a small GUI program using PySide. I am having difficulty creating another object of same class. What exactly I am trying to do is that when clicked on a button on MainWindow it should create another independent window of same class.
import sys
from PySide import QtCore, QtGui
class Sticky(QtGui.QMainWindow):
def __init__(self,parent = None):
QtGui.QMainWindow.__init__(self,parent)
self.initUI()
def initUI(self):
....
self.addToolBarElements()
....
self.show()
def addToolBarElements(self):
....
self.newwindow = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__),'icons/new.png')),"New Note",self)
self.newwindow.setStatusTip("New")
self.newwindow.triggered.connect(newwindow)
self.toolBar.addAction(self.newwindow)
def newwindow(self):
#how to create new object of same class
def run():
app = QtGui.QApplication(sys.argv)
notes = Sticky()
sys.exit(app.exec_())
Here is what I have tried:
I have tried multiprocessing but I didn't understand much. I tried calling run() method again but it gives error.
Do not call with the same name 2 different elements, in your case self.newwindow refers to the QAction as the method of the class, avoid it, that is a type of error easy to commit but difficult to find.
going to the point, you just have to create a new object of the class, but the problem is that the garbage collector will eliminate it, to avoid it there are 2 possible options, the first is to make the new window member of the class, or second store it in a list, that's the one I choose because I think you want to have several windows.
import sys
import os
from PySide import QtCore, QtGui
class Sticky(QtGui.QMainWindow):
def __init__(self,parent = None):
QtGui.QMainWindow.__init__(self,parent)
self.others_windows = []
self.initUI()
def initUI(self):
self.addToolBarElements()
self.show()
def addToolBarElements(self):
self.toolBar = self.addToolBar("toolBar")
self.newwindow = QtGui.QAction(QtGui.QIcon(os.path.join(os.path.dirname(__file__),'icons/new.png')), "New Note",self)
self.newwindow.setStatusTip("New")
self.newwindow.triggered.connect(self.on_newwindow)
self.toolBar.addAction(self.newwindow)
def on_newwindow(self):
w = Sticky()
w.show()
self.others_windows.append(w)
def run():
app = QtGui.QApplication(sys.argv)
notes = Sticky()
sys.exit(app.exec_())
run()
I try to organize my code and therefore put some stuff into modules.
I would like several variables,, such as a statusBar(), in the main code section to be altered by imported modules.
I made a quick minimal working example to show what I mean:
Here is my main.py:
from PyQt4 import QtGui
import module
import sys
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.statusBar().showMessage("Main window initalized")
module.Test()
def main():
app = QtGui.QApplication(sys.argv)
form = ApplicationWindow()
form.show()
app.exec_()
if __name__ == "__main__":
main()
Here is module.py:
from PyQt4 import QtGui
class Test(QtGui.QMainWindow):
def __init__(self):
super(Test, self).__init__()
print 'hello'
self.statusBar().showMessage("Test module called", 6000)
The code prints "hello" and does not throw me any error, so I assume the module is successfully imported and Test is initialized, but it does not alter the statusBar() in my ApplicationWindow somehow. How can I achieve that? It's probably a silly mistake, so sorry in advance for bothering you!
the Test class have to reference to the ApplicationWindow class.
self.statusBar().showMessage("Test module called", 6000) will set a message on the status bar for the window of Test (A window that is lost to the void since it is never made visible or assigned to any variable)
Passing an instance of ApplicationWindow to Test would be one way to do what you want. Test also does not need to inherit from QtGui.QMainWindow for this.
from PyQt4 import QtGui
import module
import sys
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.statusBar().showMessage("Main window initalized", 6000)
module.Test(self)
def main():
app = QtGui.QApplication(sys.argv)
form = ApplicationWindow()
form.show()
app.exec_()
if __name__ == "__main__":
main()
# module.py
class Test(object):
def __init__(self, parent):
print 'hello'
parent.statusBar().showMessage("Test module called", 6000)
I have a MainWindow class which have a Gui application running on it and i want that every time i click on a button from my application a signal is emitted and caught by another thread. There is my example code (sorry for not posting my real code but it is real big now):
from PySide.QtGui import *
from PySide.QtCore import *
import sys
import mainGui #Gui file
class MainWindow(QMainWindow, mainGui.Ui_MainWindow):
mySignal = Signal()
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.newThread = workThread()
self.newThread.start()
#myButton is part of Gui application
self.myButton.clicked.connect(self.myfunction)
def myfunction(self):
self.mySignal.emit()
(...) #Other functions and methods
class workThread(QThread):
def __init__(self, parent=None):
super(workThread, self).__init__(parent)
#The problem:
MainWindow.mySignal.connect(self.printMessage)
def run(self):
(...)
def printMessage(self):
print("Signal Recived")
(...)
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()
if __name__=="__main__":
main()
... and i get the following error:
MainWindow.mySignal.connect(self.printMessage)
AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'
There is any ideia how can i solve this?
Thanks in advance!
Signals are just like methods - they must be bound to instances. They won't work correctly if you try to access them directly via the class.
One way to fix the example is to pass the instance of MainWindow in as the parent of the thread, like so:
self.newThread = workThread(self)
...
parent.mySignal.connect(self.printMessage)
import sys
from PyQt4 import QtCore, QtGui
class Class2(object):
def __init__(self,parent):
self.welcomeScreen(self)
def welcomeScreen(self,parent):
print 'hello'
self.centralwidget=QtGui.QWidget(parent)
self.tabWidget=QtGui.QTabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(0,0,661,511))
self.tab=QtGui.QWidget()
self.lineEdit=QtGui.QLineEdit(self.tab)
self.tabWidget.addTab(self.tab,"")
self.tabWidget.show()
class Class1(QtGui.QMainWindow):
def __init__(self):
super(Class1, self).__init__()
self.func()
def func(self):
ex=Class2(self)
def main():
app = QtGui.QApplication(sys.argv)
mw = Class1()
mw.show()
sys.exit(app.exec_())
if __name__=='__main__':
main()
Ok. So during the development of a small course management system, I came across a problem wherein I need to create tabs in class other than the one where the main window is defined. The following program scales down my problem.
The problem is in the welcomeScreen(self, parent) function wherein I need to add a tab widget.
The error is: TypeError: QWidget(QWidget parent=None, Qt.WindowFlags flags=0): argument 1 has unexpected type 'Class2'
this line:
self.welcomeScreen(self)
should be
self.welcomeScreen(parent)
You are effectively passing the Class2 object to welcomeScreen twice.
self.welcomeScreen(b) is equivalent to Class2.welcomeScreen(self, b)
I am trying to write a python script to an application like matplotlib.
I need a function call to show the Qt main window. How do I do this?
class MainWindow(QtGui.QMainWindow):
def __init__(self,parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.numbers = 4
...
app = QtGui.QApplication(sys.argv)
dmw = DesignerMainWindow()
dmw.show()
sys.exit(app.exec_()) #this works, but pops the window right away
I want to be able to call the window when I wish instead. (Something like this)
def newWin():
app = QtGui.QApplication(sys.argv)
dwm = MainWindow()
sys.exit(app.exec_())
return dwn
a = newWin() # application is created now
a.numbers = 10 # do something
a.show() # should pop me the window now
EDIT : Pasting solution thanks to jadkik94
class App(QtGui.QApplication):
def __init__(self, args):
QtGui.QApplication.__init__(self,args)
self.window = MainWindow()
def doSomething(self, ii):
self.window.numbers = ii
def show(self):
self.window.show()
sys.exit(self.exec_())
a = App(sys.argv)
a.doSomething(12) #updates numbers alternately a.window.numbers = 12
a.show() #pops the window!
When used inside a function, the window does not show. The problem is simple: the window is garbage collected because it is defined inside the scope of the function, and then not used anymore, so Python sees it as "garbage" and deletes the object.
The best way I found of avoiding that is having an application class that will hold references to all the windows you want to show. So you can either have a regular class do that for you, or subclass the QtGui.QApplication if you can make use of it otherwise too. I would go for the second option.
Another option, if you really don't want to be using a class, is to set it to a global variable, and that will usually prevent it from being garbage-collected by Python.
Is this what you want:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Icon')
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
a = main()
a.show()