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)
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)
Can anyone tell me why this code is not working? The Test4 class is my converted simple UI:
import sys
import Test4
from PyQt4 import QtGui, QtCore
class UiViewer(QtGui.QApplication, Test4.Ui_Dialog):
def __init__(self, parent=None):
return super(UiViewer, self).__init__(parent)
self.setupUi(self)
def main(self):
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
uiViewer = UiViewer()
uiViewer.main()
app.exec_()
first of all
you need to use
if __name__ == '__main__'
not
if name == 'main':
and also adding the Error Message and describing the behavior of the application when you run it will help trace the problem.
from your question, it can be any number of problems.
Your UiViewer class needs to inherit from the same class as the top-level widget in Qt Designer (presumably QDialog, in your case, but it could also be a QMainWindow or a QWidget):
class UiViewer(QtGui.QDialog, Test4.Ui_Dialog):
def __init__(self, parent=None):
super(UiViewer, self).__init__(parent)
self.setupUi(self)
And note that you must not put return before the super call, otherwise the __init__ function will exit at that point, meaning the rest of its code won't be executed (in particular, setupUi would not be called).
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))