Open a GUI file from another file PyQT - python

I've created many GUI interfaces in PyQT using QT Designer, but now I'm trying to open an interface from another one, and I don't know how to do it..
Start.py is the file which run the GUI Interface Authentification_1 and Acceuil_start.py is the file which run the GUI interface Acceuil_2.py, now I want from Start.py to lunch Acceuil_start.py.
Do you have any idea about that ? Thank you.
Here's my code :
Start.py :
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow #??? Acceuil_2.py is the file which I want to open
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Fenetre_auth()
self.ui.setupUi(self)
def authentifier(val): #Slot method
self.Acceuil = Acceuil() #???
self.Acceuil.show() #???
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
Acceuil_start.py
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())

First, you should to name your GUI classes so they have a different name, and not the generic one, so you could distinct them.
Why you would need to do that? Well - simply, because it makes sense - if every class is representing different type of dialog, so it is the different type - and it should be named differently. Some of the names are/may be: QMessageBox, AboutBox, AddUserDialog, and so on.
In Acceuil_start.py (you should rename class in other module, too).
import sys
from PyQt4 import QtCore, QtGui
from Authentification_1 import Ui_Fenetre_auth
from Acceuil_2 import Ui_MainWindow
class Acceuil(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = Acceuil()
myapp.show()
sys.exit(app.exec_())
in the parent class, when you want to create the window, you are close (but it should work in any case):
def authentifier(val): #Slot method
self.Acceuil = Acceuil(self) # You should always pass the parent to the child control
self.Acceuil.show() #???
About parent issue: If your widget/window is creating another widget, setting creator object to be parent is always a good idea (apart from some singular cases), and you should read this to see why is that so:
QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shorcut is deleted too.
Edit - Minimal Working Sample
To see what I am trying to tell you, I've built a simple example. You have two classes - MainWindow and
ChildWindow. Every class can work without other class by creating separate QApplication objects. But, if you import ChildWindow in MainWindow, you will create ChildWindow in slot connected to singleshot timer which will trigger in 5 seconds.
MainWindow.py:
import sys
from PyQt4 import QtCore, QtGui
from ChildWindow import ChildWindow
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
QtCore.QTimer.singleShot(5000, self.showChildWindow)
def showChildWindow(self):
self.child_win = ChildWindow(self)
self.child_win.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())
ChildWindow.py:
import sys
from PyQt4 import QtCore, QtGui
class ChildWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle("Child Window!")
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = ChildWindow()
myapp.show()
sys.exit(app.exec_())

To reference the other dialog from Start.py, you must prefix it by the module name, which in this case is Acceuil_start. As such, it is OK if there are duplicated function names in each module. So, you would have:
def authentifier(val): #Slot method
dlg = Acceuil_start.StartQT4()
dlg.exec_()
However, if you want these to run from the same process, keep in mind that you can't have two app objects. You would probably want to structure Acceuil_start.py to act like a dialog, rather than a main window. If these are two distinct main windows, you might find it easier to just invoke another Python interpreter with the Acceuil_start.py as a parameter.

Related

How to show the stackwidget?

I'm trying to use the stackWidget to show different widgets .
However when I pressed the item on the listWdget , stackWidget below will not be displayed.
Here is my code,and I don't know where is wrong.
#!/usr/bin/python
# music_1.py
import sys
from PyQt4 import QtGui, QtCore
from music_ui import Ui_Form
class music(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.listWidget.insertItem(0,("Warm"))
self.ui.listWidget.insertItem(1,("Funny"))
self.ui.listWidget.insertItem(2,("Terror"))
self.ui.stackedWidget=QtGui.QStackedWidget()
warm=Warm()
funny=Funny()
terror=Terror()
self.ui.stackedWidget.addWidget(warm)
self.ui.stackedWidget.addWidget(funny)
self.ui.stackedWidget.addWidget(terror)
self.connect(self.ui.listWidget,QtCore.SIGNAL("currentRowChanged(int)"),self.ui.stackedWidget,QtCore.SLOT("setCurrentIndex(int)"))
class Warm(QtGui.QWidget):
def __init__(self,parent=None):
super(Warm,self).__init__(parent)
w1=QtGui.QPushButton("w1")
w2=QtGui.QPushButton("w2")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(w1)
buttonLayout.addWidget(w2)
class Funny(QtGui.QWidget):
def __init__(self,parent=None):
super(Funny,self).__init__(parent)
f1=QtGui.QPushButton("f1")
f2=QtGui.QPushButton("f2")
f3=QtGui.QPushButton("f3")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(f1)
buttonLayout.addWidget(f2)
buttonLayout.addWidget(f3)
class Terror(QtGui.QWidget):
def __init__(self,parent=None):
super(Terror,self).__init__(parent)
t1=QtGui.QPushButton("t1")
t2=QtGui.QPushButton("t2")
buttonLayout=QtGui.QHBoxLayout()
buttonLayout.addStretch(1)
buttonLayout.addWidget(t1)
buttonLayout.addWidget(t2)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = music()
myapp.show()
sys.exit(app.exec_())
I never worked with UI Files but this is my guess:
self.ui.stackedWidget=QtGui.QStackedWidget()
here you create a QStackedWidget which gets assigned to the class. The problem is that it is not added to the UI that is getting displayed but just to the instance of the Ui_Form. What you have to do is either:
Add the QStackedWidget in the UI Designer and erase the line above
or
Add the QStackedWidget to one of your layouts
which can be done like this:
self.ui.mySuperCoolLayout.addWidget(self.ui.stackedWidget)

Ui_MainWindow has no attribute 'show'

I'm writing a program which will have multiple windows. I have a main program (attached) that calls the Ui files (that have been converted into .py). The main window and customise window open correctly (the first two listed) but neither the third or fourth windows open correctly, giving me the error
'Ui_MainWindow' object has no attribute 'show'
The main program;
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = main_menu_ui.Ui_MainWindow()
mainwin.show()
sys.exit(app.exec_())
def openCustomise(self):
customiseOpen = question_set_menu_ui.Ui_MainWindow()
customiseOpen.show()
sys.exit(app.exec_())
def openQuiz(self):
quizOpen = quiz_window_ui.Ui_MainWindow()
quizOpen.show()
sys.exit(app.exec_())
def addNewSet(self):
addNewOpen = question_set_edit_ui.Ui_MainWindow()
addNewOpen.show()
sys.exit(app.exec_())
Sorry if I'm missing something obvious, I'm learning Qt/Python for college.
The auto-generated UI class that you are importing extends object and doesn't have a show method (open up the .py file for yourself and verify this).
In general, you should structure your GUIs like this:
from PyQt4 import QtCore, QtGui
import sys
from layout_file import main_menu_ui
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = main_menu_ui()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = MyForm()
mainwin.show()
sys.exit(app.exec_())
You import your UI from your autogenerated UI file. You have a class that contains your GUI logic. It then sets up your UI layout from your imported UI in its __init__() method.

Load other windows when button clicked. PyQt

I am trying to call another window from a button click in python 2.7 using PyQt4. The code below opens the AddBooking dialog but immediately closes it. Im new to Gui programming, can somebody please tell me what is wrong with my code?
from PyQt4 import QtGui
from HomeScreen import Ui_HomeScreen
from AddBooking import Ui_AddBooking
import sys
class HomeScreen(QtGui.QWidget, Ui_HomeScreen):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.show()
self.Add_Booking_Button.clicked.connect(self.handleButton)
def handleButton(self):
AddBooking2()
class AddBooking2(QtGui.QWidget, Ui_AddBooking):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = HomeScreen()
window.show()
sys.exit(app.exec_())
Don't use multi-inheritance and neither call show function inside class initializer. The problem is that the object you are creating with AddBooking2() is a temporal and it's destroyed automatically when the function ends. So you need use some variable to reference that object something like:
addbooking = AddBooking2()
addbooking.show()
Also, since you are working with QtDesigner and pyuic4 tools you can make connections a little bit easier. Said that, your code can be modified:
from PyQt4 import QtGui
from PyQt4.QtCore import pyqtSlot
from HomeScreen import Ui_HomeScreen
from AddBooking import Ui_AddBooking
import sys
class HomeScreen(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_HomeScreen()
self.ui.setupUi(self)
#pyqtSlot("")
def on_Add_Booking_Button_clicked(self): # The connection is carried by the Ui_* classes generated by pyuic4
addbooking = AddBooking2()
addbooking.show()
class AddBooking2(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_AddBooking()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = HomeScreen()
window.show()
sys.exit(app.exec_())
The dialog closes immediately because you are not keeping a reference to it, and so it will get garbage-collected as soon as it goes out of scope.
The simplest way to fix it would be to do something like this:
def handleButton(self):
self.dialog = AddBooking2()
self.dialog.show()
and you can also remove the self.show() lines from AddBooking2.__init__ and HomeScreen.__init__, which are redundant. Other than that, your code looks fine.

Running python files

I am working on pyqt4 and python26 application.I created forms using qt designer (.ui files).
I converted them to .py and .pyc files.But when i try to run .py file ,python command line comes and goes within a second,the form (corresponding .ui file) cannot be seen...what can be the problem??
this is my code:(.py file)
from DlgAbout_ui import Ui_DlgAbout
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import resources
class DlgAbout(QDialog, Ui_DlgAbout):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setupUi(self)
self.logo.setPixmap( QPixmap( ":/icons/faunalia_logo.png" ) )
text = self.txt.toHtml()
text = text.replace( "$PLUGIN_NAME$", "RT Sql Layer" )
self.txt.setHtml(text)
First, don't use:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
Instead:
from PyQt4 import QtCore, QtGui
And reference the modules explicitly.
class DlgAbout(QtGui.QDialog, Ui_DlgAbout):
etc.
In your code, all you've done is defined a dialog box. You haven't defined any main application to run, or any way to show the dialog box.
For an example, here's a basic main application to run:
from PyQt4 import QtGui
import sys
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.form_widget = FormWidget(self)
self.setCentralWidget(self.form_widget)
class FormWidget(QtGui.QWidget):
def __init__(self, parent):
super(FormWidget, self).__init__(parent)
self.layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton("Button!")
self.layout.addWidget(self.button)
if __name__ == "__main__":
app = QtGui.QApplication([])
foo = MyMainWindow()
foo.show()
sys.exit(app.exec_())
This defines a main window, and a form (Which MyMainWindow sets up, as you can see).
I then check if this is the main file being run (if __name__ == "__main__":), and I start the application (The app = QtGui.QApplication([]), create the main window, and show the main window.
In your case, you could define a main application like I did, and make it alert your QDialog.
Your python code just imports some modules and then defines a new class. It doesn't do anything with the class it has defined, though. In other words, once Python is done creating the new class, it is finished, and it exits.
I don't know PyQT at all, but most likely you need to start the GUI's main loop, and also instantiate an instance of your new class and pass it to PyQT.

Basic Widget Interaction with PyQt

Please can someone tell me what im doing wrong here with respect to calling pwTxt.text.
#!/usr/bin/python
import sys
from PyQt4 import QtCore, QtGui
from mainwindow import Ui_MainWindow
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def on_pwExtract_pressed(self):
print self.pwTxt.text
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
The line print self.pwTxt.text fails because it can't find the widget, pwTxt is a QLineEdit defined on the main window. I just made it in QTDesigner and generated python code with pyuic4.
How do I correctly reference other widgets on the same window, in this case I just want to get the text from a QLineEdit named pwTxt when the QPushButton pwExtract is pressed.
Thanks a lot.
Try:
print self.ui.pwTxt.text()

Categories