pyqt5, Receiving AttributeError: 'QMainWindow' object has no attribute 'browseSlot' - python

I'm learning pyqt5, and specifically how to use it with the QT Designer. I'm sort of following the turorial HERE. However in this tutorial they are converting the XML interface to Python code with pyuic5, while I'm trying to import it dynamically with uic.loadUi("myui.ui"). In the tutorial we define a slot with the signals and slot editor named " browseSlot".
When I try to run/compile, at the line
dlg = uic.loadUi("myui.ui")
I get the error:
AttributeError: 'QMainWindow' object has no attribute 'browseSlot'
I think what's going on is that QT Designer connects a signal to the slot 'browseSlot' but because a 'browseSlot' method isn't defined in the myui.ui, the error is thrown, because there is no way for the interpreter to know I'm referring to a method that is outside the UI interface file. (In this case, in the module that loads the interface). As far as I can tell QT Designer only lets me connect signals to slots, not define a whole new one. I think that way this is handled in other frameworks is that there will be an abstract method that needs over riding. So what can I do in this situation to make it work?
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import QObject, pyqtSlot
import sys
app = QtWidgets.QApplication([])
dlg = uic.loadUi("myui.ui")
#pyqtSlot
def returnPressedSlot():
pass
#pyqtSlot
def writeDocSlot():
pass
#pyQt
def browseSlot():
pass
dlg.show()
sys.exit(app.exec())

The slots belong to the class that is used returns loadUi(), they are not any functions since they do not magically not connect them, if you want to use loadUi() and implement these methods you must inherit from the class corresponding to the template that you used, in the example of the link Main Window was used so it must be inherited from QMainWindow:
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
uic.loadUi("mainwindow.ui", self)
#QtCore.pyqtSlot()
def returnPressedSlot():
pass
#QtCore.pyqtSlot()
def writeDocSlot():
pass
#QtCore.pyqtSlot()
def browseSlot():
pass
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

try this out
from PyQt5 import QtWidgets, uic
app = QtWidgets.QApplication([])
form = uic.loadUi("login.ui")
form2.show()
app.exec()
the above python code should display your gui app properly as long as you have install PyQt5 and PyQt5-tools,if you haven't then open CMD and typeenter code here "pip install PyQt5" and click enter.once installation is done type "pip install PyQt5-tools" then you are good to go

Related

PyQt6 Accessing UI Object Attributes

I'm trying to create a simple GUI in Python using PyQt6 and Qt Designer.
I've already made the .ui file, and am able to load it properly and have it shown when running the code.
I can't, however, seem able to access any of the objects, i.e buttons and such.
When I print out the children of the AppWindow object I do see all of them listed, but I can't change their attributes via self.button (inside the class init function)- it says 'unresolved attribute reference'.
To my understanding it's supposed to be something trivial, so I'm not quite sure what I had managed to get wrong here.
Would appreciate any help since I'm stumped.
Thank you.
Here's my code-
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt6.QtCore import Qt
from PyQt6 import uic
class AppWindow(QWidget):
def __init__(self):
super().__init__()
uic.loadUi('gui.ui', self)
self.setWindowTitle('API-SF App')
if __name__ == '__main__':
app = QApplication(sys.argv)
app_window = AppWindow()
app_window.show()
sys.exit(app.exec())

How to load a Qt Designer file (.ui) in a QWizardPage using PySide2

I want to design my QWizardPages in Qt Designer and I want to load them into my Python program with PySide2. Previously I have been using PyQt5 without any problems but making the switch to PySide2 seems harder then expected.
The problem I am facing is that when I am adding a QWizardPage to my QWizard , the page is indeed added to the Wizard, but also an other (empty) page is added. I'm not able to find what I'm doing wrong so I was wondering if someone can have a look.
I have tried to add the pages with both the functions addPage() and setPage(), but they give the same results. What I also noticed is that when I explicitely set the Title of the page with setTitle(), the empty (unwanted) page gets this title, but not the page I designed in Qt Designer.
import os
import sys
from PySide2.QtWidgets import QWizard, QWizardPage, QApplication
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
from enum import Enum
class MyWizard(QWizard):
def __init__(self):
super().__init__()
self.setPage(PageNumbers.page_one.value, PageOne(self))
class PageOne(QWizardPage):
def __init__(self, parent):
super().__init__(parent)
ui_file = os.path.join(__file__, '..', 'pageOne.ui')
file = QFile(ui_file)
file.open(QFile.ReadOnly)
loader = QUiLoader()
loader.load(file, parent)
file.close()
self.setTitle("This is another test Title")
class PageNumbers(Enum):
page_one = 1
if __name__ == '__main__':
app = QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
app.exec_()
What I would expect is to have just one QWizardPage showing up with directly the Finish button. Instead I get two QWizardPages as shown in this image:
Can someone tell me what's going on?
(I get the expected result using PyQt5 with the following code: https://pastebin.com/6W2sx9M1)
The developers of PyQt implement functions to be able to create classes based on the .ui that is not implemented in Qt by default (Qt/C++ uses the MOC to do this work), but in the case of PySide2-Qt for python it does not implement it, only has the QUiLoader class that allows to create a widget based on the .ui unlike PyQt that allows filling a class.
In conclusion there is no equivalent in PySide2 of the loadUi function so you can not implement the same logic. PySide2 is not PyQt5, there are own equivalences since they use the same base but they have implementations, limitations and advantages.
Going to the practical problem, considering that the .ui is next to the .py the solution is the following:
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
from enum import Enum
class PageNumbers(Enum):
page_one = 0
class MyWizard(QtWidgets.QWizard):
def __init__(self):
super().__init__()
ui_file = os.path.join(os.path.dirname(os.path.abspath(__file__)) ,'PageOne.ui')
page_one = create_widget(ui_file, self)
self.setPage(PageNumbers.page_one.value, page_one)
def create_widget(filename, parent=None):
file = QtCore.QFile(filename)
if not file.open(QtCore.QFile.ReadOnly):
return
loader = QtUiTools.QUiLoader()
widget = loader.load(file, parent)
return widget
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
sys.exit(app.exec_())

How can I self hide and show QDialog() in PyQT5?

I have a GUI that was generated using Qt Designer, I used pyuic5 to generate a .py file. In a separate py (program.py) file I import my UI a do all my work there.
program.py
import sys, os, time
from subprocess import call
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyCred_GUI import Ui_Dialog
class MyGUI(Ui_Dialog):
def __init__(self, dialog):
Ui_Dialog.__init__(self)
self.setupUi(dialog)
self.pushButton_2.clicked.connect(self.cancelbutton)
def cancelbutton(self):
exit()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
dialog = QtWidgets.QDialog()
dialog.setWindowFlags(QtCore.Qt.WindowSystemMenuHint)
prog = MyGUI(dialog)
dialog.show()
sys.exit(app.exec_())
I pulled a lot out just to focus on the issue here. When I click my Cancel button, I want the window to hide, set a timer, and then reappear after so many seconds. I have tried every combination of self.close() self.hide() self.destroy() and none of them hide my window. I get an error that says
"AttributeError: 'MyGUI' object has no attribute 'hide'"
Which makes sense because MyGUI doesn't have a hide() function. I am at a complete loss on how to hide this window.
EDIT (Solved)
For future people, as suggested by Hi Im Frogatto dialog.hide() worked.
In your code snippet, dialog is of type QDialog and thereby having hide method. However instances of MyGUI class seem to not have such a method. So, if you write dialog.hide() in that __init__() function, you can hide it.

AttributeError: 'StartQT4' object has no attribute 'accept'

I'm trying to program a quick dialog with QT4 and Python.
I've generated the Python class, using pyuic4, and tried to make a small python script to start it up:
import sys
from PyQt4 import QtCore, QtGui
from ConfigGUI import Ui_ConfigGUI
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_ConfigGUI()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = StartQT4()
myapp.show()
sys.exit(app.exec_())
When I try to run it, it says AttributeError: 'StartQT4' object has no attribute 'accept'.
What did I do wrong?
I managed to reproduce your problem. You selected a form based on dialogs in the QtDesigner, but are trying to construct it inside a QMainWindow.
The UI code tries to bind its buttons to default dialog slots acceptand reject which are not available in a QMainWindow.
From ConfigGUI.py:
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
The class contains a method called setupUi(). This takes a single argument which is the widget in which the user interface is created. The type of this argument (typically QDialog, QWidget or QMainWindow) is set in Designer. We refer to this type as the Qt base class.
-- http://pyqt.sourceforge.net/Docs/PyQt4/designer.html
So, either select Main Window in the Designer as a base class, or change the inheritance of StartQT4 to QtGui.QDialog.

How do I open sub window after I click on button on main screen in PyQt4

HI I am trying to make a simple converter.
I have used PyQt4 designed to make the Gui
I want to know how launch a new window after I click on the individual button.
This is the interface I have created using PyQt4 Designer.
Here is the Image link :
and I want to launch this windows when I click on currency button.
Here is the Image Link:
Here is my code for main.py
from PyQt4 import QtGui
from main_screen import mainscreen
def main():
import sys
qApp = QtGui.QApplication(sys.argv)
aw = mainscreen()
aw.show()
sys.exit(qApp.exec_())
if __name__ == '__main__':
main()
and code for mainscreen.py
from PyQt4 import QtCore, QtGui
from window_main import Ui_MainWindow
class mainscreen(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(mainscreen,self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
How can I open new window after I click on currency button (object name for currency button is "currency_bt")
and do I have to write the code for currency in same window or I have to write in new window.
How do I do it.
I am new to Python Gui programming.
Each GUI form that you create in Qt Designer needs to be converted into a python module using pyuic. So, to start with, you need to do the same for currency.ui that you did for window_main.
Now you can import your currency window class into mainscreen.py, and connect a button to handler so you can display it.
The code would look something like this:
from PyQt4 import QtCore, QtGui
from window_main import Ui_MainWindow
from currency import Ui_CurrencyWindow
class CurrencyWindow(QtGui.QMainWindow, Ui_CurrencyWindow):
def __init__(self, parent=None):
super(CurrencyWindow, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setupUi(self)
class MainScreen(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainScreen, self).__init__(parent)
self.setupUi(self)
self.currencyButton.clicked.connect(self.handleCurrencyButton)
def handleCurrencyButton(self):
window = CurrencyWindow(self)
window.show()
After looking at this example code, it will probably occur to you that you are going to end up importing a lot of modules, and have a lot of boiler-plate code to write for each one of them (which is not much fun).
So I would advise you to consider changing your GUI design, so that you have one main window containing a tabwidget, and then have a separate tab for each of your converters. This will not only make your application much easier to write, but it should also make it a lot nicer to use.
I'm making my bachelor thesis in PyQt4. First I also wanted to use the designer (generating code is nice), but afterall I was not using it during my work. Maybe it's a matter of taste.
But for your question (I did this without the QtDesigner):
Let's say we have a main window class:
import sys
from PyQt4 import QtCore, QtGui
class mainscreen(QtGui.QMainWindow):
def __init__(self, parent=None):
super(mainscreen,self).__init__(parent)
self.button = QtGui.QPushButton("push")
self.button.clicked.connect(self.pushed)
#pyqtSlot()
def pushed(self):
# in this section here you can create the new window and show it
qApp = QtGui.QApplication(sys.argv)
aw = mainscreen()
aw.show()
sys.exit(qApp.exec_())
There are some good tutorials (http://zetcode.com/gui/pyqt4/ helped me getting started).
Make two programs: main_win.py and second_win.py, then in main_win.py put this lines:
from os import system as sh //In the begin
def openewin(self): //In the class main_win
sh("python second_win.py")
Ready, just connect the push button to function openewin!

Categories

Resources