Qlistwidget mistake not defined - python

I would like to make a QListwidget with a scroll bar. I'm a complete beginner in pyqt and I'm trying to understand it. I though to create it with the following code but it is wrong.
self.list = QListWidget(self)
data = QListWidgetItem(list)
data.setText('1')
self.list = QListWidget(self)
NameError: global name 'QListWidget' is not defined
If someone can explain my why it's wrong I'll appreciate that.

QListWidget is defined under QtGui. So you need to reference that in some way.
Either you could do from PyQt4.QtGui import QListWidget or as in the example below explicitly say where it is located.
from PyQt4 import QtGui, QtCore
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.list = QtGui.QListWidget(self)
self.list.addItems([str(i) for i in range(10)])
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.list)
if __name__ == '__main__':
app = QtGui.QApplication([])
ex = MyWidget()
ex.show()
app.exec_()

Related

How to get parent widget's name printed from child widget class?

I understand that question is simple, but I'm stuck anyway.
Is there any method to get parent layout widget name from inherited widget class?
I have a small piece of code here. So basically I need to get printed self.super_main_layout in the label field where "Push the button" printed now.
I have a function def print_foo which should do that. But I don't know how to get parent() name from inherited class. I need to get exactly this self.super_main_layout printed in label field.
I've tried to use self.parent() method but it doesn't work
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtWidgets import QApplication
class ButtonTest(QtWidgets.QWidget):
def __init__(self):
super(ButtonTest, self).__init__()
self.setFixedSize(300, 100)
self.layout = QtWidgets.QHBoxLayout()
self.setLayout(self.layout)
self.label = QtWidgets.QLabel("Push the Button")
self.button = QtWidgets.QPushButton("Button")
self.button.clicked.connect(self.print_foo)
self.layout.addWidget(self.label)
self.layout.addWidget(self.button)
def print_foo(self):
### ???????????
self.label.setText(str(self.parent().parent())) # ????
print(self.parent()) # ????
class MyApp(QtWidgets.QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.W = ButtonTest()
self.setFixedSize(300,300)
self.super_main_layout = QtWidgets.QVBoxLayout()
self.setLayout(self.super_main_layout)
self.super_main_layout.addWidget(self.W)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyApp()
w.show()
sys.exit(app.exec_())
So now it prints None in label field when you push Button.
But I want layout widget self.super_main_layout to be printed.
Is there any way to do that? I'm working on a bigger project right now. And I'm programming only inherited class with button in which I have to get different parent names when button is pressed.
Thank you very much.
ps. I'm quite new to this site and programming at all, so sorry for any mistakes. Thanks in advance!
The name of a variable is impossible in itself to obtain because the names of the variables are relative, for example if the code were the following:
# ...
self.setFixedSize(300,300)
self.super_main_layout = QtWidgets.QVBoxLayout()
foo_obj = self.super_main_layout
self.setLayout(foo_obj)
self.super_main_layout.addWidget(self.W)
What is the name of the layout: self.super_main_layout or foo_obj? As both variables refer to the same object.
What you can get is the object itself using the parent and then its layout:
def print_foo(self):
pw = self.parentWidget()
if pw is not None:
print(pw.layout())

PySide: event-filter for QGraphicsView in container class

I have communications working between similar widgets from imported child widgets and the parent main window and widgets. However, I am stumped when it comes to a QGraphicsScene widget imported as a module and sub-widget. I have put some simplified files below. So, QGraphicsView (from the QGraphicsScene) will be the actual widget I need to emit and signal events to other QWidgets inside the main window.
If I have all classes in one file, it works but if I have the classes as separate modules, I get "does not have attribute" errors, specifically in the simple version here for QGraphicsScene .viewport
Attribute Error "self.graphicsView.viewport().installEventFilter(self)"
I guess that the composite graphics widget is actually now a QWidget and I am not initialising the imported module functions/attributes for the QGraphicsView element. Thing is, I want it to exist that way so I can separate the GUI elements and functions of different modules. The others I have used so far have been straightforward QWidget to QWidget signals derived from QObjects, so work fine, but I haven't been able to achieve the same with the imported QGraphicsScene to QWidgets since it errors when it tries to reach QGraphicsView within the main window. Again, all fine if all classes exist in one large file.
Any kind person can point out my error here? How can I separate the module scripts to behave the same way as the single script?
Working single script:
# QWidgetAll.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
The same file as separate modules. qWidgetView.py errors with attribute error:
# qWidgetView.py
from PySide import QtGui, QtCore
from qGraphicView import GraphicsView
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = WidgetView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
with imported qGraphicView.py module:
# qGraphicView.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
You need to filter events for the QGraphicsView that is a child widget of the GraphicsView class, because you only want mouse-moves on the graphics-view itself, not the whole container widget. So I would suggest something like this:
The qGraphicView.py module:
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsView.setMouseTracking(True)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
def viewport(self):
return self.graphicsView.viewport()
The qWidgetView.py module:
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)

How can I add items in listWidget?

I have trouble adding item in listWidget
I made UI with QT creator and want to import it in python.
When I run this code the items doesn't shows in listWidget, only white blanks.
what is the problem??
please help me
my code is
import sys
from PyQt4 import QtCore, QtGui
from secdialog import Ui_SecDialog
class SecDialog(QtGui.QDialog, Ui_SecDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.setupUi(self)
self.listWidget.addItem("QlistItem_1");
self.listWidget.addItem("QlistItem_2");
self.listWidget.addItem("QlistItem_3");
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Ui_SecDialog()
ex.show()
sys.exit(app.exec_())
You create an instance of Ui_SecDialog in ex but you want to create a SecDialog instance:
ex = SecDialog()

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)

PyQt4: how to make undercorated window with reserved space

I'd like to make a panel-like application using PyQt4 for Linux. for this i need the window i created:
to be undecorated
to have reserved space
to appear on all workspaces
From reading the documentation i've got the idea that i should use QtWindowFlags. But i have no clue as to how to do that. Also i believe there should be a Qt.WindowType hint somewhere telling the WM the window's a "dock" application. I have made this with pygtk following this thread, but here with Qt i don't really know how to handle this. (I need Qt for its ability to theme/skin application more easily.)
Below is the current code i made (nothing extraordinary).
import sys
from PyQt4 import QtGui
class Panel(QtGui.QWidget):
def __init__(self, parent=None): ## should the QtWindowFlag be here?
QtGui.QWidget.__init__(self, parent) ## should the QtWindowFlag be there as well?
self.setWindowTitle('QtPanel')
self.resize(QtGui.QDesktopWidget().screenGeometry().width(), 25)
self.move(0,0)
def main():
app = QtGui.QApplication(sys.argv)
panel = Panel()
panel.show()
sys.exit(app.exec_())
return 0
if __name__ == '__main__':
main()
Can anyone help me with this? Thanks :)
Read about the QWidget.windowFlags property: http://doc.qt.nokia.com/4.7/qwidget.html#windowFlags-prop
Example:
>>> from PyQt4 import QtGui, QtCore
>>> app = QtGui.QApplication([])
>>> win = QtGui.QMainWindow()
>>> win.setWindowFlags(win.windowFlags() | QtCore.Qt.FramelessWindowHint)
>>> win.show()
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
qbtn = QtGui.QPushButton('Quit', self)
#qbtn.clicked.connect(QtCore.QCoreApplication.instance().quit)
qbtn.clicked.connect(self.test)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('Quit button')
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
self.show()
def test(self):
print "test"
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The solution is to use Python-Xlib, and it has been described in an answer on a universal way to reserve screen space on X.

Categories