Qt Multiple GraphicsEffects - python

Is there a way in Qt5 to apply a QGraphicsEffect to a widget, even when one of its parent widgets already has a QGraphicsEffect applied to it?
When i try the following:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class ParentWidget(QWidget):
def __init__(self,parent):
super().__init__(parent)
effect = QGraphicsBlurEffect(self)
self.setGraphicsEffect(effect)
effect.setBlurRadius(0)
class ChildWidget(ParentWidget):
def __init__(self,parent):
super().__init__(parent)
self.layout = QGridLayout(self)
widget = QWidget()
widget.setObjectName('reviewControlArea')
effect = QGraphicsOpacityEffect(widget)
widget.setGraphicsEffect(effect)
self.layout.addWidget(widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
MainWindow = QMainWindow()
cw = ChildWidget(MainWindow)
MainWindow.setCentralWidget(cw)
MainWindow.show()
sys.exit(app.exec_())
The stdout says:
QPainter::begin: A paint device can only be painted by one painter at a time.

Related

PyQT layouts: why does QVBoxLayout stack the buttons instead of creating the layout? [duplicate]

I'm making an application in PyQt4 and this is my code so far:
import sys
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle('Main Menu')
self.setFixedSize(1200, 625)
self.firstWidgets()
self.show()
def firstWidgets(self):
self.vbox1 = QtGui.QVBoxLayout()
self.task1 = QtGui.QLabel('Check 1', self)
self.task1CB = QtGui.QCheckBox(self)
self.hbox1 = QtGui.QHBoxLayout()
self.hbox1.addWidget(self.task1)
self.hbox1.addWidget(self.task1CB)
self.vbox1.addLayout(self.hbox1)
self.setLayout(self.vbox1)
def main():
application = QtGui.QApplication(sys.argv)
gui = MainWindow()
sys.exit(application.exec_())
if __name__=='__main__':
main()
My problem is in MainWindow.firstWidgets(). I try to set a layout but I get an error even though that's my first time using .setLayout for that form, which confuses me.
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "",
which already has a layout
You can't set a QLayout directly on the QMainWindow. You need to create a QWidget and set it as the central widget on the QMainWindow and assign the QLayout to that.
wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)
NOTE: This is for Qt4 -- see the other answer on this question for the Qt5 updated code.
Just an update to Brenden Abel's answer:
QWidget and QVBoxLayout (for Python3, PyQt5) are now contained in the PyQt5.QtWidgets module and not the PyQt5.QtGui module.
So updated code:
wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
layout = QtWidgets.QVBoxLayout()
wid.setLayout(layout)
This is an example using PyQt5
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('My App')
# Cannot set QxxLayout directly on the QMainWindow
# Need to create a QWidget and set it as the central widget
widget = QWidget()
layout = QVBoxLayout()
b1 = QPushButton('Red' ); b1.setStyleSheet("background-color: red;")
b2 = QPushButton('Blue' ); b2.setStyleSheet("background-color: blue;")
b3 = QPushButton('Yellow'); b3.setStyleSheet("background-color: yellow;")
layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)
widget.setLayout(layout)
self.setCentralWidget(widget)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

PyQt5 Layouts not moving button [duplicate]

I'm making an application in PyQt4 and this is my code so far:
import sys
from PyQt4 import QtGui, QtCore
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.initUi()
def initUi(self):
self.setWindowTitle('Main Menu')
self.setFixedSize(1200, 625)
self.firstWidgets()
self.show()
def firstWidgets(self):
self.vbox1 = QtGui.QVBoxLayout()
self.task1 = QtGui.QLabel('Check 1', self)
self.task1CB = QtGui.QCheckBox(self)
self.hbox1 = QtGui.QHBoxLayout()
self.hbox1.addWidget(self.task1)
self.hbox1.addWidget(self.task1CB)
self.vbox1.addLayout(self.hbox1)
self.setLayout(self.vbox1)
def main():
application = QtGui.QApplication(sys.argv)
gui = MainWindow()
sys.exit(application.exec_())
if __name__=='__main__':
main()
My problem is in MainWindow.firstWidgets(). I try to set a layout but I get an error even though that's my first time using .setLayout for that form, which confuses me.
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "",
which already has a layout
You can't set a QLayout directly on the QMainWindow. You need to create a QWidget and set it as the central widget on the QMainWindow and assign the QLayout to that.
wid = QtGui.QWidget(self)
self.setCentralWidget(wid)
layout = QtGui.QVBoxLayout()
wid.setLayout(layout)
NOTE: This is for Qt4 -- see the other answer on this question for the Qt5 updated code.
Just an update to Brenden Abel's answer:
QWidget and QVBoxLayout (for Python3, PyQt5) are now contained in the PyQt5.QtWidgets module and not the PyQt5.QtGui module.
So updated code:
wid = QtWidgets.QWidget(self)
self.setCentralWidget(wid)
layout = QtWidgets.QVBoxLayout()
wid.setLayout(layout)
This is an example using PyQt5
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('My App')
# Cannot set QxxLayout directly on the QMainWindow
# Need to create a QWidget and set it as the central widget
widget = QWidget()
layout = QVBoxLayout()
b1 = QPushButton('Red' ); b1.setStyleSheet("background-color: red;")
b2 = QPushButton('Blue' ); b2.setStyleSheet("background-color: blue;")
b3 = QPushButton('Yellow'); b3.setStyleSheet("background-color: yellow;")
layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)
widget.setLayout(layout)
self.setCentralWidget(widget)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Python PyQt5 Create Layout

I'm trying to create a layout with pyqt5, but i cannot do it. There are so many error. Why i am getting so many errors.
autoFillBackground() takes no arguments, and MainWindow will not assume the palette of it's central widget unless you explicitly set it. Also, this has nothing to do with a layout.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Color(QWidget):
def __init__(self, color):
super().__init__()
self.autoFillBackground()
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
widget = Color('Blue')
self.setCentralWidget(widget)
self.setPalette(widget.palette())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())

Put a QToolBar in a QWidget instead of QMainWindow

I am trying to put a QToolBar on a layout of a QWidget instead of QMainWindow. On QMainWindow and QWidget is working fine, but when i try to add it on a layout first, is not. Am I doing something wrong? Is it possible? Here is my code:
from PyQt4 import QtGui, QtCore
import sys
img = '../../Images/logo.png'
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainWin = QtGui.QMainWindow()
widget = QtGui.QWidget()
hLayout = QtGui.QHBoxLayout()
'''ToolBar On main Window '''
basicToolBar = mainWin.addToolBar('Basic')
basicToolBar.addAction(QtGui.QAction('Test', mainWin))
# basicToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', mainWin))
# mainWin.show()
'''ToolBar On Widget '''
# Case 1: Set widget as parent
# widgetToolBar = QtGui.QToolBar(widget)
# widgetToolBar.addAction(QtGui.QAction('Test', widget))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), QtGui.QAction('Test', widget))
# Case 2: Set toolBat on a layout
widgetToolBar = QtGui.QToolBar()
widgetToolBar.addAction(QtGui.QAction('Test', None))
# widgetToolBar.addAction(QtGui.QAction(QtGui.QIcon(img), 'Test', None))
hLayout.addWidget(widgetToolBar)
widget.setLayout(hLayout)
widget.show()
# Run
sys.exit(app.exec_())
QToolBar can only be in a QMainWindow since the QMainWindow has a special layout.
So you can use a secondary QMainWindow without problems as I show below:
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.tabwidget = QtGui.QTabWidget()
self.setCentralWidget(self.tabwidget)
for name in ("tab1", "tab2", "tab3"):
self.create_widgets(name)
def create_widgets(self, name):
w = QtGui.QMainWindow()
self.tabwidget.addTab(w, name)
basicToolBar = w.addToolBar('Basic')
basicToolBar.addAction('Test')
basicToolBar.addAction(QtGui.QIcon("home.png"), 'Test')
tab = QtGui.QTabWidget()
w.setCentralWidget(tab)
for i in range(10):
tab.addTab(QtGui.QWidget(), "tab-{}".format(i))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Hmmm have you read the description of QToolBar? http://doc.qt.io/qt-5/qtoolbar.html#details
I think it won't work like this if your Object isn't a child of QMainWindow. The documentation says:
When a QToolBar is not a child of a QMainWindow, it loses the ability to populate the extension pop up with widgets added to the toolbar using addWidget(). Please use widget actions created by inheriting QWidgetAction and implementing QWidgetAction::createWidget() instead.

PyQt5 behavior of setParent to display QWidget without layout

There has been a small problem with a little project of mine using PyQt5. I tried to add a random QWidget (in this example a QPushbutton) to a custom QWidget. However, I don't understand the behavior of the "setParent" function. When I use it outside of the custom QWidget, the QPushButton is displayed. When I use it in a declared function of the custom Widget, the QPushButton is occluded and I have no chance of displaying it outside of adding a layout (which I don't want). Here an example of the source code:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class customWidget(QWidget):
def __init__(self):
super().__init__()
self.addButton()
def addButton(self):
button = QPushButton('not_showing')
button.setParent(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
button = QPushButton('showing')
button.setParent(w)
button.move(50,50)
w.resize(600,600)
w.move(1000,300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
There is no change, when adding the parent during the initialization of the QPushButton.
When the function addButton exits, the button is removed.
If you want to see the button, try this:
class customWidget(QWidget):
def __init__(self):
super().__init__()
self.addButton()
self.button = None
def addButton(self):
if self.button is None:
self.button = QPushButton('not_showing')
self.button.setParent(self)
You do not have this problem in the main function because this function does not return until the application is stopped.
EDIT: The comment was right, but you also missed some arguments. This will work
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class customWidget(QWidget):
def __init__(self, parent=None):
super(customWidget, self).__init__(parent)
self.addButton()
def addButton(self):
button = QPushButton('not_showing')
button.setParent(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = customWidget()
button = QPushButton('showing')
button.setParent(w)
button.move(50,50)
w.resize(600,600)
w.move(1000,300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())

Categories