How to rectify the python error: "icon object is not callable"? - python

I have a dictionary where there are certain elements and associated keys. I want to create a GUI to display the items. I have used a QMessageBox PyQt widget within a for loop. But when i run the code i am getting a following error:
Traceback (most recent call last): File "C:\Python34_64bit\dictt.py", line 50, in main() File "C:\Python34_64bit\dictt.py", line 45, in main GUI=MYGUI() File "C:\Python34_64bit\dictt.py", line 31, in init self.Choice=QtGui.QMessageBox.Question(self,k,val,QtGui.QMes‌​sageBox.Yes | QtGui.QMessageBox.No) TypeError: 'Icon' object is not callable
Kindly help me how to fix this issue with a modification to my code. Below is my code:
import sys
from PyQt4 import QtGui,QtCore
class MYGUI(QtGui.QWidget):
def __init__(self):
super(MYGUI,self).__init__()
self.setWindowTitle("GUI")
#widgets:
self.labl=QtGui.QLabel(self)
self.labl.setFont(QtGui.QFont('Calibri', 34))
#Layout:
Layout =QtGui.QVBoxLayout()
Layout.addWidget(self.labl)
Layout.addStretch()
self.setLayout(Layout)
#Actions:
Queries={'Q1':'question 1','Q2':'question2'}
for k,val in Queries.items():
self.Choice=QtGui.QMessageBox.Question(self,k,val,QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if choice==QtGui.QMessageBox.Yes:
self.labl.setText('yes')
else:
self.labl.setText('No')
self.show()
def main():
app=QtGui.QApplication(sys.argv)
GUI=MYGUI()
sys.exit(app.exec_())
main()

Your problem is just with lower/upper case.
QMessageBox.Question is the icon
QMessageBox.question(parent, title, text, button0, button1) is the function
See: https://srinikom.github.io/pyside-docs/PySide/QtGui/QMessageBox.html

Related

How to access components from another module with PyQt6?

I made a minimum working environment for this question.
First I have this UI file (GDrive Link),which I'll later load in my UI.py., which I'll later load in my
The UI.py goes thus:
import sys
from PyQt6.QtWidgets import QMainWindow, QApplication, QPlainTextEdit
from PyQt6 import uic
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.ui = uic.loadUi(r"C:\Documents\Qt Designer\mwe.ui") # Change it to yoour own .ui
self.txtBox = self.findChild(QPlainTextEdit, 'plainTextEdit')
self.ui.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
import main
sys.exit(app.exec())
Essentially, what I want to do is to access this PlainTextEditor in main.py, becuase that's where I'll write the functions.
import UI
UI.Window.txtBox.insertPlainText('foo')
But when I try to run UI.py, I get this error:
Traceback (most recent call last):
File "C:\Users\Me\PycharmProjects\dynamic_ui_foo\UI.py", line 18, in <module>
import main
File "C:\Users\Me\PycharmProjects\dynamic_ui_foo\main.py", line 3, in <module>
UI.Window.txtBox.insertPlainText('foo')
AttributeError: type object 'Window' has no attribute 'txtBox'
It says Window doesn't have this attribute. How do I access the components from another module? And am I going in the right way by separating UI codes and function codes (I know the cross-importing looks terrible).
To illustrate your error message, consider the following example:
class bla:
def __init__(self):
self.foo = 'test'
print(bla.foo) # <-- results in your error
b = bla()
print(b.foo) # <-- this is what you would like to access
Right now you are trying to access txtBox of the class Window, but you need to access txtBox from your instance window.
However, I have doubts about it working in the way you do your imports.
I would suggest to move
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
sys.exit(app.exec())
to main.py. Use UI.py to only define the layout. Changing the text txtBox can be implemented either as a method of Window:
class Window(QMainWindow):
# init code
def change_content(self, content):
self.txtBox.insertPlainText(content)
Then in main you call that:
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
window.change_content()
sys.exit(app.exec())
Of course you can use a more direct approach:
if __name__ == "__main__":
app = QApplication(sys.argv)
window = UI.Window()
window.txtBox.insertPlainText(content)
sys.exit(app.exec())
The last example seems to be easier. But that way, if you change txtBox to something else you need to keep in mind to also do changes in main.py. With the first example you only have to do changes in UI.py.
Edit:
Added missing argument self. Thanks to musicamante for pointing that out.

PyQt5 QGraphicsView object has no attribute 'resetMatrix'?

Consider this PyQT5 example, let's call it test.py (for me, behaves the same under both python2 and python3 on Ubuntu 18.04):
#!/usr/bin/env python
from __future__ import print_function
import sys, os
from PyQt5 import QtCore, QtWidgets, QtGui
class PhotoViewer(QtWidgets.QGraphicsView):
def __init__(self, parent):
super(PhotoViewer, self).__init__(parent)
self.parent = parent
#self.resetMatrix() # SO: 39101834, but "AttributeError: 'PhotoViewer' object has no attribute 'resetMatrix'"
self.scale(1.0, 1.0)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.setWindowTitle("test.py")
self.setMinimumWidth(1000)
self.setMinimumHeight(600)
self.viewer = PhotoViewer(self)
wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
VBlayout = QtWidgets.QVBoxLayout()
VBlayout.addWidget(self.viewer)
wid.setLayout(VBlayout)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
main = MainWindow()
main.show()
sys.exit(app.exec_())
If I run it as is, it runs fine, without a problem.
If I uncomment the commented self.resetMatrix() line, then the program fails with:
$ python test.py
Traceback (most recent call last):
File "test.py", line 29, in <module>
main = MainWindow()
File "test.py", line 20, in __init__
self.viewer = PhotoViewer(self)
File "test.py", line 11, in __init__
self.resetMatrix() # SO: 39101834, but "AttributeError: 'PhotoViewer' object has no attribute 'resetMatrix'"
AttributeError: 'PhotoViewer' object has no attribute 'resetMatrix'
But this I find rather bizarre, because PhotoViewer inherits from QGraphicsView, calling PhotoViewer.scale() which is a QGraphicsView method is clearly not a problem - and How to reset the scale in QGraphicsView? documents that calling QGraphicsView()->resetMatrix() should be possible, and also it is documented for both:
http://pyqt.sourceforge.net/Docs/PyQt4/qgraphicsview.html#resetMatrix
http://pyqt.sourceforge.net/Docs/PyQt5/api/QtWidgets/qgraphicsview.html -> "The C++ documentation can be found here." -> https://doc.qt.io/qt-5/qgraphicsview.html#resetMatrix
What is the mistake I'm making - why cannot I call resetMatrix in this case; and what should I do to be able to call this function?
It seems that it is a bug of PyQt5, I have tested it with PySide2 and it works correctly. But there is a workaround, if you check the source code you see that the the resetMatrix() method calls only resetTransform() so it uses that method.
class PhotoViewer(QtWidgets.QGraphicsView):
def __init__(self, parent):
super(PhotoViewer, self).__init__(parent)
self.parent = parent
self.resetTransform() # self.resetMatrix()
self.scale(1.0, 1.0)

How can I go back and forth through two windows in PyQt5

I am using PyQt5 to create two windows, main window and info window. I want to go back and forth through them, such that
initial state:
if main window is opened
I can click button info
If button info is clicked
info window is opened, main is closed
I can click main button
3.
If main button is clicked
info window is opened, main is closed
However, If I'd run the program from main window,
I'll be able to go to info, but not come back to main, through main button
Traceback (most recent call last):
File "~/Description.py", line 259, in Show_Main
Info.close()
NameError: name 'Info' is not defined
similarly, If I'd run the program from info window, I'd be able to go to main, but not back to info
Traceback (most recent call last):
File "~/M.py", line 259, in Show_Main
Form.close()
NameError: name 'Info' is not defined
This is partial code from each .py file:
M.py
from Description import Ui_Form
class Main_Form(object):
def setupUi(self, Form):
Form.setObjectName("Main")
.
.
.
def Show_Description(self):
self.DWindow = QtWidgets.QWidget()
self.ui = Ui_Form()
self.ui.setupUi2(self.DWindow)
self.DWindow.show()
Form.close()
descrpition.py
class Ui_Form(object):
def setupUi2(self, Info):
Info.setObjectName("info")
def Show_Main(self):
from M import Main_Form
self.DWindow = QtWidgets.QWidget()
self.ui = Main_Form()
self.ui.setupUi(self.DWindow)
self.DWindow.show()
Info.close()
Don't ask me why am I importing Main_Form inside the Show_Main method rather than out of it, it would return an error otherwise.
Your error message is saying that it can not recognize variable Info. From the code you've uploaded, variable Info is given to the class Ui_Form through the function setupUi2. But fucntion Show_main, the one that is creating error, does not share the variable Info that is given to the setupUi2, because it's not an instance variable. I guess you can try something like this :
def setupUi2(self,Info):
self.Info = Info
self.Info.setObjectName("info")
def Show_Main(self):
~~~
self.Info.close()

PyQt4 QTextBrowser.append Does'nt show any output

i just started to learn PyQt and GUI programing and
i copied this code exactly from the book "Rapid GUI Programming with Python and Qt:The Definitive Guide to PyQt Programming" and it supposed to show a calculator that calculates an expression.
when i run the application main window shows up but does not do anything and since i copied the code form a well known pyqt book it's very strange.
i am using python 3.4.4 and pyqt4 .this is the code i copied from book:
import sys
from math import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):
def __init__(self,parent=None):
super(Form, self).__init__(parent)
self.browser = QTextBrowser()
self.lineedit = QLineEdit("Type an expression and press Enter")
self.lineedit.selectAll()
layout = QVBoxLayout()
layout.addWidget(self.browser)
layout.addWidget(self.lineedit)
self.setLayout(layout)
self.lineedit.setFocus()
self.connect(self.lineedit, SIGNAL("retrunPressed()"),
self.updateUi)
self.setWindowTitle("Calculate")
def updateUi(self):
try:
text= unicode(self.lineedit.text())
self.browser.append("{0} = <b>{1}</b>".format(text,eval(text)))
except:
self.browser.append(
"<font color=red>%s is invalid!</font>" % text)
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
these are the errors i get:
Traceback (most recent call last):
File "calculator.pyw", line 25, in updateUi
text = unicode(self.lineedit.text())
NameError: name 'unicode' is not defined
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "calculator.pyw", line 29, in updateUi
"%s is invalid!" % text)
UnboundLocalError: local variable 'text' referenced before assignment
i know its not good idea to ask someone else to debug my code but i did all i could about it and nothing came up.
thanks
You have a typo in your signal name it should be
self.connect(self.lineedit, SIGNAL("returnPressed()"),
not
self.connect(self.lineedit, SIGNAL("retrunPressed()"),
so apparently you didn't copy it well, also it seems that book was written in python2 so you don't need the unicode function strings in python3 are already unicode by default

Difficulty with inheritance in PyQt

I'm trying to run an example from the book "Rapid GUI Programming with Python and QT" and I'm getting an error message.
import sys
from math import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Form(QDialog):
def __init__(self,parent = None):
super(Form,self).__init__(parent)
self.browser = QTextBrowser()
self.lineedit = QLineEdit("Type an Expression and press enter")
self.lineedit.selectAll()
layout = QBoxLayout()
layout.addWidget(self.browser)
layout.addWidget(self.lineedit)
self.setLayout(layout)
self.lineedit.setFocus()
self.connect(self.lineedit, SIGNAL("returnPressed()"),self.UpdateGUI)
self.setWindowTitle("Ryans App")
def UpdateGUI(self):
try
text = self.lineedit.text()
self.browser.append("%s = <b>%s</b>" % (text,eval(text)))
except:
self.browser.append("<font color=red>%s is Invalid!</font>" % text )
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
The trace I'm getting is:
Traceback (most recent call last):
File "C:\Users\MyName\workspaces\LearningProject\src\LearningModule.py", line 33, in <module>
form = Form()
File "C:\Users\MyName\workspaces\LearningProject\src\LearningModule.py", line 16, in __init__
layout = QBoxLayout()
TypeError: QBoxLayout(QBoxLayout.Direction, QWidget parent=None): not enough arguments
I'm confused as to why it's requiring an argument to create the Form object as I'm just trying to inherit from QDialog... am I missing a subtlety in the syntax?
The version I have uses QVBoxLayout instead:
...
self.lineedit.selectAll()
layout = QVBoxLayout()
layout.addWidget(self.browser)
...
My understanding is that since it lines the widgets up vertically, the .LeftToRight and parent are not strictly necessary.
I'm using the most recent code archive for python 2.6 from the book website.
When creating a QBoxLayout, you need to specify a direction (e.g. QBoxLayout.LeftToRight) and optionally a parent (in this case, self should work as the parent).
These should be added on your layout = QBoxLayout() line.

Categories