Python PyQt5 Create Layout - python

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_())

Related

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()

How to create a Widget using .ui file?

I'd like to create a widget inside a MainWindow that gets its design from a file created with QtDesigner.
the .ui file I created is test.ui
I have a MainWindow instance inheriting from QMainWindow that will create a stacked widget with many widgets inside it. For simplicity in this example, it will create just a widget as central widget.
The My Widget instance inside the MainWindow is the one that has to grab its design from the .ui file
As it is, the application shows a blank window
Here is the code:
from PySide2.QtWidgets import QMainWindow, QApplication, QDesktopWidget, QWidget
from PySide2.QtCore import QCoreApplication, Qt
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QFile
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
ui_file = QFile("test.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui_dim_percentage = 70/100
self.initUI()
def initUI(self):
self.center()
self.home_widget = MyWidget(self)
self.setCentralWidget(self.home_widget)
self.show()
def center(self): # resizes the UI to a percentage of the screen and centers the widget
screen_size = QDesktopWidget().screenGeometry()
self.resize(screen_size.width()*self.ui_dim_percentage, screen_size.height()*self.ui_dim_percentage)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
How should I correct the code?
The problem is that you are confusing concepts, when you use QUiLoader you are creating the window that in this case is the window variable that is a local variable, that is, the .ui does not fill in MyWidget.
The solution is not to create the MyWidget class, just use the window variable.
from PySide2.QtWidgets import QMainWindow, QApplication, QDesktopWidget
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
def create_widget():
ui_file = QFile("test.ui")
if ui_file.open(QFile.ReadOnly):
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
return window
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui_dim_percentage = 70 / 100
self.initUI()
def initUI(self):
self.center()
self.home_widget = create_widget()
self.setCentralWidget(self.home_widget)
self.show()
# resizes the UI to a percentage of the screen and centers the widget
def center(self):
screen_size = QDesktopWidget().screenGeometry()
self.resize(
screen_size.width() * self.ui_dim_percentage,
screen_size.height() * self.ui_dim_percentage,
)
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
import sys
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Have you tried to convert your ui-file?
You can use pyuic4 command on shell:
pyuic4 test.ui -o test.py

How to remove the white frame around the background?

The code below generates a window with a black background. Unfortunately the background is framed by a thin white line.
I've tried to set other background parameters to black, but it didn't work out.
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
class GraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super(GraphicsWindow, self).__init__(parent)
scene = QGraphicsScene(self)
self.setScene(scene)
self.setBackgroundBrush(Qt.black)
def main():
app = QApplication(sys.argv)
graphics_window = GraphicsWindow()
graphics_window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I wanted to create a window with an entirely black background, but it has a thin white frame.
You have to change the background color of the QGraphicsView as for example with QPalette:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene
class GraphicsWindow(QGraphicsView):
def __init__(self, parent=None):
super(GraphicsWindow, self).__init__(parent)
scene = QGraphicsScene(self)
self.setScene(scene)
self.setBackgroundBrush(Qt.black)
pal = self.palette()
pal.setColor(QPalette.Window, Qt.black)
self.setPalette(pal)
def main():
app = QApplication(sys.argv)
graphics_window = GraphicsWindow()
graphics_window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
You can add css styles inside the init method of your class:
def __init__(self, parent=None):
super(GraphicsWindow, self).__init__(parent)
scene = QGraphicsScene(self)
self.setScene(scene)
self.setBackgroundBrush(Qt.black)
self.setStyleSheet("border:0px")

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_())

Qt Multiple GraphicsEffects

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.

Categories