PyQt4 trouble creating a simple GUI application - python

so I'm creating a simple windows application with Python and PyQt4. I've designed my UI the way I want it in QtCreator and I've created the necessary .py file from the .ui file. When I try to actually open an instance of the window however I'm given the following error:
AttributeError: 'Window' object has no attribute 'setCentralWidget'
So I go back into the ui_mainwindow.py file and comment out the following line:
MainWindow.setCentralWidget(self.centralWidget)
Now when I run main.py it will generate an instance of the window but it loses its grid layout and the UI elements just sort of float there. Any idea what I'm doing wrong?
My main.py file:
import sys
from PyQt4.QtGui import QApplication
from window import Window
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
and my window.py file:
from PyQt4.QtCore import Qt, SIGNAL
from PyQt4.QtGui import *
from ui_mainwindow import Ui_MainWindow
class Window(QWidget, Ui_MainWindow):
def __init__(self, parent = None):
QWidget.__init__(self, parent)
self.setupUi(self)

You need to inherit from QMainWindow, not QWidget. setCentralWidget is a method of QMainWindow.
from PyQt4.QtCore import Qt, SIGNAL
from PyQt4.QtGui import *
from ui_mainwindow import Ui_MainWindow
class Window(QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
QMainWindow.__init__(self, parent)
# or better
# super(Window, self).__init__(parent)
self.setupUi(self)

Related

PySide2 QUiLoader returns an empty window

PySide2(5.6.0~a1) Qt UI file loader returns an empty window whereare PyQt5 loader works fine. Could you explained to me where I am wrong.
Non Working PySide2 version:
import sys
from PySide2.QtWidgets import QDialog, QApplication
from PySide2 import QtUiTools
class AppWindow(QDialog):
def __init__(self):
super().__init__()
self.ui = QtUiTools.QUiLoader().load("dialog1.ui")
self.show()
app = QApplication(sys.argv)
w = AppWindow()
sys.exit(app.exec_())
Working PyQt5 version:
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5 import uic
class AppWindow(QDialog):
def __init__(self):
super().__init__()
self.ui = uic.loadUi("dialog1.ui", self)
self.show()
app = QApplication(sys.argv)
w = AppWindow()
sys.exit(app.exec_())
Using this function also does not work :
def loadUiWidget(uifilename, parent=None):
loader = QtUiTools.QUiLoader()
uifile = QtCore.QFile(uifilename)
uifile.open(QtCore.QFile.ReadOnly)
ui = loader.load(uifile, parent)
uifile.close()
return ui
In PySide2 there's no function to QMainWindow class overwrite itself. It's necessary to show the ui:
import sys
from PySide2.QtWidgets import QDialog, QApplication
from PySide2 import QtUiTools
class AppWindow(QDialog):
def __init__(self):
super().__init__()
self.ui = QtUiTools.QUiLoader().load("dialog1.ui")
self.ui.show()
app = QApplication(sys.argv)
w = AppWindow()
sys.exit(app.exec_())
QUiLoader().load() returns the widget as an object so if you assign it to a variable it will not do anything, you should use show():
import sys
from PySide2.QtWidgets import QApplication
from PySide2 import QtUiTools
app = QApplication(sys.argv)
w = QtUiTools.QUiLoader().load("dialog1.ui")
w.show()
sys.exit(app.exec_())
If you want to load QMainWindow from designer *.ui file you can use
import sys
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtUiTools import QUiLoader
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setCentralWidget(QUiLoader().load("form.ui"))
but slot-signal bindings, which are set in the designer in *.ui file, are not working anyway.
So, for full-function use of designer GUI and slot-signal bindings, the only way I found is to compile *.ui file to python module with pyside UI compiler:
pyside2-uic mainwindow.ui > ui_mainwindow.py
and then include produced ui_mainwindow. In this method the slot-signal pairs from Qt UI designer will work well.
import sys
from PySide2.QtWidgets import QApplication, QMainWindow
from ui_mainwindow import Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)

PyQt: how to load multiple .ui Files from Qt Designer

I want to add startup window that when I click button, it will open another window and close current window. For each window, it has seperated UI which created from Qt Designer in .ui form.
I load both .ui file via uic.loadUiType(). The first window(first UI) can normally show its UI but when I click button to go to another window, another UI (second UI) doesn't work. It likes open blank window.
Another problem is if I load first UI and then change to second UI (delete that Class and change to another Class, also delete uic.loadUiType()), the second UI still doesn't work (show blank window)
Please help... I research before create this question but can't find the answer.
Here's my code. How can I fix it?
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
from PyQt5 import uic
#load both ui file
uifile_1 = 'UI/openPage.ui'
form_1, base_1 = uic.loadUiType(uifile_1)
uifile_2 = 'UI/mainPage.ui'
form_2, base_2 = uic.loadUiType(uifile_2)
class Example(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
self.startButton.clicked.connect(self.change)
def change(self):
self.main = MainPage()
self.main.show()
class MainPage(base_2, form_2):
def __int__(self):
super(base_2, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())
First you have an error, you must change __int__ to __init__. To close the window call the close() method.
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
from PyQt5 import uic
#load both ui file
uifile_1 = 'UI/openPage.ui'
form_1, base_1 = uic.loadUiType(uifile_1)
uifile_2 = 'UI/mainPage.ui'
form_2, base_2 = uic.loadUiType(uifile_2)
class Example(base_1, form_1):
def __init__(self):
super(base_1,self).__init__()
self.setupUi(self)
self.startButton.clicked.connect(self.change)
def change(self):
self.main = MainPage()
self.main.show()
self.close()
class MainPage(base_2, form_2):
def __init__(self):
super(base_2, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

create main script to use PyQt4 windows with other objects

I am trying to learn how to use python and pyQt.
I have done a window with Qtcreator then I used pyuic4, I have also created a class called Ruban I would like to use it with my window interface. In my window I have a button called nouveauRuban. I would like to create an object from my class Ruban when this button is clicked.
I know my code is wrong, the problem may be at the initial part of mainTN, on the __init__ ?
# -*- coding: utf-8 -*-
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from mainwindow import Ui_MainWindow
from Ruban import Ruban
class mainTM(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None): #, parent=None ??
super (mainTM, self).__init__(self, parent) #(parent) ??
self.createWidgets()
self.nouveauRuban.connect(nouveauRuban, QtCore.SIGNAL(_fromUtf8("clicked()")), self.nvRuban)
def nvRuban(self):
self.ruban=Ruban()
self.ruban.info_ruban()
def createWidgets(self):
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
if __name__== "__main__":
app=QApplication(sys.argv)
myapp=mainTM()
myapp.show()
sys.exit(app.exec_())
Here is a re-write of your script which should fix all the problems:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from mainwindow import Ui_MainWindow
from Ruban import Ruban
class mainTM(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(mainTM, self).__init__(parent)
self.setupUi(self)
self.nouveauRuban.clicked.connect(self.nvRuban)
def nvRuban(self):
self.ruban = Ruban()
self.ruban.info_ruban()
if __name__== '__main__':
app = QApplication(sys.argv)
myapp = mainTM()
myapp.show()
sys.exit(app.exec_())
If you're connecting a signal to a slot, you need to define that slot using a decorator:
#QtCore.pyqtSlot()
def nvRuban(self):
self.ruban=Ruban()
self.ruban.info_ruban()
Then connect it:
self.nouveauRuban.clicked.connect(nvRuban)

In PyQT4, how can I hide the window title of a child widget?

I am working in PyQT4 with Qt Designer. My goal is to hide the title bar of a widget.
I know there is a method like widget.setWindowFlags (QtCore.Qt.CustomizeWindowHint) or widget.setWindowFlags (QtCore.Qt.FramelessWindowHint), but it doesn't work in my case.
My widget is a child of QWorkspace. That means my widget was added to Qworspace. I am trying to hide the title bar in the same way, but it doesn't work.
Does anybody knows how to remove the program's title bar in this case?
My Code: I tried with both methods. They have been commented out.
Edit:
modul: search.py
from PyQt4.QtGui import QWidget
from PyQt4.uic import loadUi
from PyQt4.QtCore import Qt
class Search_Window(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent, Qt.FramelessWindowHint)
self.getPath_search_ui = os.path.join(os.path.abspath("."), 'files', "qt_ui", 'pp_search.ui')
self.ui_pp_search = loadUi(self.getPath_search_ui, self)
modul: mdi.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
from PyQt4.QtGui import QMainWindow, QWorkspace
from PyQt4.QtCore import Qt
from PyQt4.uic import loadUi
from ..modules_ui.ui_pp_search import Search_Window
class Mdi_Main(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.getPath_mdi = os.path.join(os.path.abspath("."), 'files', "qt_ui", 'pp_mdi.ui')
self.ui_TestMainWorkSpace = loadUi(self.getPath_mdi, self)
self.ui_TestMainWorkSpace.showMaximized()
self.workspace = QWorkspace()
self.workspace.setScrollBarsEnabled(True)
self.setCentralWidget(self.workspace)
def create_action_menu(self):
self.ui_TestMainWorkSpace.actionSearch.triggered.connect(self.show_search_form)
def show_search_form(self):
search_form = Search_Window()
self.workspace.addWindow(search_form, Qt.FramelessWindowHint)
search_form.show()
You can see I try to hide the title bar by adding search_form to workspace. Its also doesn't work.
The following snippet works for me, by specifying the window flags to the addWindow method:
from PyQt4.QtGui import QApplication, QWorkspace, QTableView
from PyQt4.QtCore import Qt
def main():
app = QApplication([])
workspace = QWorkspace()
view = QTableView()
workspace.addWindow(view, Qt.FramelessWindowHint)
workspace.show()
app.exec_()
if __name__ == '__main__':
main()

Creating widgets in a different class

I have the mainwindow in the 'DataClass'.How can I create widgets in another class(the HelloClass)
test.py
import sys
import label
from PyQt4 import QtGui, QtCore
class DataClass(QtGui.QMainWindow):
def __init__(self):
super(DataClass, self).__init__()
self.window()
def window(self):
ex=label.HelloClass(self)
ex.print_label()
def main():
app = QtGui.QApplication(sys.argv)
ob=DataClass()
ob.show()
sys.exit(app.exec_())
if __name__=='__main__':
main()
and this is the 'label.py' file:
import sys
from PyQt4 import QtGui, QtCore
class HelloClass(QtGui.QMainWindow):
def print_label(self):
self.la=QtGui.QLabel("hello",self)
self.la.move(300,100)
self.la.show()
import sys
from PyQt4 import QtGui, QtCore
class HelloClass(QtGui.QMainWindow):
def print_label(self):
self.la=QtGui.QLabel("hello",self)
self.la.move(300,100)
self.la.show()
You can't have two QMainWindow class, you should just not inherit from QMainWindow on HelloClass. And if you are setting parent to label then set it your DataClass which is your QMainWindow.
class HelloClass(object):
def print_label(self, parent):
self.la = QtGui.QLabel("hello", parent)
self.la.move(300, 100)
self.la.show()
class DataClass(QtGui.QMainWindow):
def __init__(self):
super(DataClass, self).__init__()
self.window()
def window(self):
ex = label.HelloClass()
ex.print_label(self)
But to be honest, the best way to create GUI using PyQt is to use QtDesigner. Create your .ui file with QtDesigner and then create .py file with command pyuic4 your.ui -o ui_your.py.
-- UPDATE --
Your controller class for using gui created by QtDesigner would look like this:
from ui_objects import Ui_Objects # this is class created with QtDesigner, name of class is a 'Ui_' + name of main Object in QtDesigner
class Objects(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.ui = Ui_Objects()
self.ui.setupUi(self)
# then you can add your own code, in example connect your own methods to actions for widgets

Categories

Resources