I am using Python 3.9.1 and PyQt6. Now I want to create a window with blurred background, which should look something like below:
Blurred Window Background Demo
It would be helpful if anybody provide me a code for this.
the real deal:
python -m pip install BlurWindow
import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from BlurWindow.blurWindow import blur
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setAttribute(Qt.WA_TranslucentBackground)
self.resize(500, 400)
blur(self.winId())
self.setStyleSheet("background-color: rgba(0, 0, 0, 0)")
if __name__ == '__main__':
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Well taken from KDE Plasma, its easy now to do this with Python.
For details, check this out - Watch this carefully
You will need to use the library provided called fluentapp -
For Project made with python - size 95 mb
You will need to extract it from the project and use the reference guide provided.
I have already tried it its cool and enhances the beauty of your app.
Syntax is easy e.g. -
import fluentapp.pyqt6.windowtools as wingui
wingui.setWindowAlpha("0.5") # Make window transparent
wingui.addGaussianBlur(radius=20, cover= False)
#if you want to use additional layer for dark and light theme, you can set cover True for dark.
Your Code Here ----
Related
A long time ago, I wanted to make a logo appear on top of the text in a QPushButton stacked on top of each other, but I couldn't find anyway
I read some stylesheets (couldn't find a single doc to read it all about all styles I can apply to a button)
tried the setLayoutDirection (RightToLeft and LeftToRight were there, but no UpToDown direction)
In my (I wish) last attempt I tried to inherit a QAbstractButton (I didn't find QAbstractPushButton, so I guess QAbstractButton is the answer) and change its paintEvent/paintEngine to draw an image or maybe add a vbox inside it as a layout to draw to components, but I can't find anything in python (specially PySide) which has an example in any possible way close to that. The best thing I found was the analogue clock example which was not very helpful because it was trying to work a QWidget and not a QAbstractButton and I want to keep the feel of a Native looking button.
I like my final product to be something like this.
source of the implemention of that
Python Enaml toolkit supported this feature out of the box (in one of its widgets), and I know it is QT based, so I really wish to know how it is possible?
p.s.: Also, is there a market for qt widgets? e.g.: a plugin system. Because rewriting an android like switch doesn't seem like the correct thing that I should do! even a good tutorial or doc would be appreicated (excluding official doc)
It is easier than you think, you can use QToolButton() like this:
import sys
from PySide6.QtCore import Qt, QSize
from PySide6.QtWidgets import QApplication, QVBoxLayout,QStyle, QWidget,
QToolButton
class Window(QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
button = QToolButton()
# here you choose the position of the icon and its text
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonTextUnderIcon)
# here I just use built-in icon by PySide6 for this example
name = 'SP_DialogSaveButton'
pixmapi = getattr(QStyle, name)
icon = self.style().standardIcon(pixmapi)
# here we set text and icon of size 32x32 to the button
button.setIcon(icon)
button.setText("Sample text")
button.setIconSize(QSize(32, 32))
# finally we add our button to the layout
lay = QVBoxLayout(self)
lay.addWidget(button, alignment=Qt.AlignCenter)
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
I am using PyQtGraph and am really enjoying it, but have hit upon an issue that may force me to move to something else.
I am displaying medical images (CT/MRI etc.) as numpy 2D or 3D arrays in the ImageView which gives the nice slider view for volume data. The problem is theses images are often low res (256x256) and when viewed on large monitors or just zoomed-in they look blocky and horrible.
How can I show these images antialiased? This seems to be possible as mentioned here:
How can anti-aliasing be enabled in a pyqtgraph ImageView?
and a few other places suggesting all you need to do is:
import pyqtgraph as pg
pg.setConfigOptions(antialias=True)
and enable antialiasing in the graphics view, which I assume would be this:
myImageViewWidget = pg.ImageView(parent=None)
myImageViewWidget.ui.graphicsView.setAntialiasing(True)
But this doesn't seem to do anything different in my code. What am I doing wrong?
I'm using Windows 10 (but need it to work on MacOs - Darwin), Python 3.7, PySide 2 (5.15.12) and PyQtGraph 0.12.3
'Minimum' code to reproduce the issue (not quite but I want to keep ImageView subclassed as that's how I have it in my code):
import sys
from PySide2.QtWidgets import (
QApplication,
QHBoxLayout,
QMainWindow,
QWidget,
)
import pyqtgraph as pg
import numpy as np
pg.setConfigOptions(antialias=True)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.cw = QWidget(self)
self.cw.setAutoFillBackground(True)
self.setCentralWidget(self.cw)
self.layout = QHBoxLayout()
self.cw.setLayout(self.layout)
self.ImgWidget = MyImageWidget(parent=self)
self.layout.addWidget(self.ImgWidget)
self.show()
class MyImageWidget(pg.ImageView):
def __init__(self, parent=None):
super().__init__(parent)
self.ui.histogram.hide()
self.ui.roiBtn.hide()
self.ui.menuBtn.hide()
self.ui.graphicsView.setAntialiasing(True)
# 5 frames of 50x50 random noise
img = (1000 * np.random.normal(size=(5, 50, 50))) - 500
self.setImage(img)
def main():
app = QApplication()
main = MainWindow()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
What you're referring to is not antialiasing.
Antialiasing "smoothens" the portions of an image that cannot "fit" precisely a single physical pixel.
What you are seeing is in fact the opposite, as each source pixel is actually large enough to be shown as it is: a square that possibly occupies more physical pixels.
What you probably want is a blur effect, which can be achieved through a QGraphicsBlurEffect set on the self.imageItem of the view:
class MyImageWidget(pg.ImageView):
def __init__(self, parent=None):
# ...
self.blurEffect = QGraphicsBlurEffect(blurRadius=1.1)
self.imageItem.setGraphicsEffect(self.blurEffect)
Note that since the image item is always scaled and the blur effect is proportional, you might need to adjust the blur radius to even smaller values depending on the shown resolution (but still bigger than 1.0).
I'm trying to change the current color group fora QPalette, but it seems that the setCurrentColorGroup method of QPalette simply does not work.
I'm running this code:
app = QtGui.QApplication(sys.argv)
button = QPushButton()
svgWidget = QSvgWidget(resources_paths.getPathToIconFile("_playableLabels/42-labelPlay-disabled-c.svg"))
button.setLayout(QHBoxLayout())
button.layout().addWidget(svgWidget)
button.setFixedSize(QSize(300, 300))
print button.palette().currentColorGroup()
button.setEnabled(False)
print button.palette().currentColorGroup()
button.palette().setCurrentColorGroup(QPalette.ColorGroup.Normal)
print button.palette().currentColorGroup()
button.show()
print button.palette().currentColorGroup()
app.exec_()
This is the output I get:
PySide.QtGui.QPalette.ColorGroup.Normal
PySide.QtGui.QPalette.ColorGroup.Disabled
PySide.QtGui.QPalette.ColorGroup.Disabled
PySide.QtGui.QPalette.ColorGroup.Disabled
Process finished with exit code -1
So... It seems that setCurrentColorGroup does exactly nothing. Any ideas on how could I change the current color group?
Thanks in advance!
(BTW, I'm running PySide 1.2.4 with Qt 4.8 on a Windows 7 system)
It seems that you are trying to change the way icons are rendered, rather than the way widgets are painted, so the palette is not the right API to use. Instead, you should use a QIcon, which allows different images to be used for various modes and states.
To use the same image for both Normal and Disabled modes, you would use code like this:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Normal)
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Disabled)
button = QtGui.QPushButton()
button.setIcon(icon)
However, you should take careful note of this warning from the Qt docs:
Custom icon engines are free to ignore additionally added pixmaps.
So there is no guarantee that this will work with all widget styles on all platforms.
UPDATE:
If the above method doesn't work, it probably means the widget style is controlling how disabled icons are rendered. The relevant QStyle API is generatedIconPixmap, which returns a copy of the pixmap modified according to the icon mode and style options. It seems that this method may sometimes also take the palette into account (somewhat contrary to what I stated above) - but when I tested this, it did not have any affect. I reset the palette like this:
palette = self.button.palette()
palette.setCurrentColorGroup(QtGui.QPalette.Normal)
palette.setColorGroup(QtGui.QPalette.Disabled,
palette.windowText(), palette.button(),
palette.light(), palette.dark(), palette.mid(),
palette.text(), palette.brightText(),
palette.base(), palette.window(),
)
button.setPalette(palette)
which made the colours look normal when the button was disabled - but the icon was still greyed out. Still, you might want to try it in case things work differently on your platform (don't be surprised if they don't).
It seems that the correct way to control the disabling of icons is to create a QProxyStyle and override the generatedIconPixmap method. Unfortunately, this class is not available in PyQt4, but I have tested it in PyQt5, and it works. So the only working solution I have at the moment is to upgrade to PyQt5, and use QProxyStyle. Here is a demo script that shows how to implement it:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ProxyStyle(QtWidgets.QProxyStyle):
def generatedIconPixmap(self, mode, pixmap, option):
if mode == QtGui.QIcon.Disabled:
mode = QtGui.QIcon.Normal
return super(ProxyStyle, self).generatedIconPixmap(
mode, pixmap, option)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.button = QtWidgets.QPushButton(self)
self.button.setIcon(QtGui.QIcon('image.svg'))
self.button2 = QtWidgets.QPushButton('Test', self)
self.button2.setCheckable(True)
self.button2.clicked.connect(self.button.setDisabled)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.button)
layout.addWidget(self.button2)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle(ProxyStyle())
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
The QMainWindow below is assigned a dark-gray background-color using QSS.
I would also like to change the color of the borders and the color of the title bar.
How to achieve control of the appearance of the QMainWindow borders and titlebar?
I would like to know how to change their colors and how to control the borders width and the title-bar's height.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
appStyle="""
QMainWindow{
background-color: darkgray;
}
"""
class GUI(QMainWindow):
def __init__(self):
super(GUI, self).__init__()
self.setStyleSheet(appStyle)
if __name__ == '__main__':
if not QApplication.instance(): app=QApplication([])
w=GUI()
w.setStyleSheet(appStyle)
w.show()
w.raise_()
sys.exit(app.exec_())
To my knowledge you cannot (on Windows maybe with some special OS dependent calls) modify the borders and header of a top-level widget (real window on the desktop) in Qt because these are delivered from the operating system.
You can however, set the widget frameless and add borders for yourself.
Example:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
app.setStyleSheet('QMainWindow{background-color: darkgray;border: 1px solid black;}')
w = QtGui.QMainWindow()
w.setWindowFlags(QtCore.Qt.FramelessWindowHint)
w.show()
app.exec_()
And looks like
You see that unfortunately the usually header bar vanishes, so no dragging, no resizing, no closing or minimizing. This then all must be implemented yourself. See for example How can I handle events in the titlebar and change its color etc ?.
This can be implemented in QT C++ by detecting current system theme from Windows registry and applying the Dark Window hints. A dark style in addition to this can make dark light window modes.
A sample project demonstrating this is shared here if it helps to adapt
https://envyen.com/posts/2021-10-24-QT-Windows-Dark-theme/
I need to perform lot of operations on an image. So I used OpenCV. OpenCV is very efficient in image processing, however it is not too good to present a suitable GUI. So I decided to use PyQt to draw a custom GUI and OpenCV to process my image.
I created a very simple program you directly picked from the documentation. I simply read a jpg picture and save it in a png format by pressing the key s.
My aim is to replace the key s with a button to press to perform the same action using PyQt. Also, I want the window displayed by PyQt to have the same behavior as OpenCV: mainly speaking, the function imshow() displays a window that fits to the image size.
Here is my OpenCV simple code:
import numpy
import cv2
class LoadImage:
def loadImage(self):
img = cv2.imread('photo.jpg')
cv2.imshow('Image on a window',img)
k = cv2.waitKey(0)
if k == 27:
cv2.destroyAllWindows()
elif k == ord('s'):
cv2.imwrite('photopng.png',img)
cv2.destroyAllWindows()
if __name__=="__main__":
LI=LoadImage()
LI.loadImage()
Output:
Here is a simple PyQt code to draw a simple window:
import sys
from PyQt4 import QtGui
class DrawWindow:
def drawWindow(self):
app=QtGui.QApplication(sys.argv)
w=QtGui.QWidget()
#w.resize(250,250)
w.move(300,300)
w.setWindowTitle("Simple Window")
w.show()
sys.exit(app.exec_())
if __name__=="__main__":
DW=DrawWindow()
DW.drawWindow()
How can I mix the 2 codes to reach my goal?
Modified some code basing on your post, I didn't use the Opencv to render the image, instead using QPixmap to render it. then use KeyPressEvent to capture the user input .
# -*- coding: utf-8 -*-
import numpy
import cv2
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MyDialog(QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
self.cvImage = cv2.imread(r'cat.jpg')
height, width, byteValue = self.cvImage.shape
byteValue = byteValue * width
cv2.cvtColor(self.cvImage, cv2.COLOR_BGR2RGB, self.cvImage)
self.mQImage = QImage(self.cvImage, width, height, byteValue, QImage.Format_RGB888)
def paintEvent(self, QPaintEvent):
painter = QPainter()
painter.begin(self)
painter.drawImage(0, 0, self.mQImage)
painter.end()
def keyPressEvent(self, QKeyEvent):
super(MyDialog, self).keyPressEvent(QKeyEvent)
if 's' == QKeyEvent.text():
cv2.imwrite("cat2.png", self.cvImage)
else:
app.exit(1)
if __name__=="__main__":
import sys
app = QApplication(sys.argv)
w = MyDialog()
w.resize(600, 400)
w.show()
app.exec_()
You can create a QImage directly from the image data read by OpenCV, convert that to a QPixmap using QPixmap.fromImage and then use that to set the pixmap of a QLabel using the setPixmap method.
This page shows how to view a webcam feed by using PySide and OpenVC: https://gist.github.com/bsdnoobz/8464000. I made it work for videos as well, by commenting out these two lines
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, self.video_size.width())
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, self.video_size.height())
and instead using
resized_bgr_frame = cv2.resize(
bgr_frame,
(self.video_size.width(), self.video_size.height()),
interpolation=cv2.INTER_CUBIC if self.video_size.width() > bgr_frame.shape[1] else cv2.INTER_AREA)
on the video frame (where bgr_frame is the frame that was obtained with self.capture.read()).
(Note that there is some different naming and namespace conventions for the OpenCV constants going on here, perhaps due to differing cv2 versions?)