Search code examples
pythonpyqtpyside

How to keep in PyQt/PySide QLinearGradient always in the middle?


I am trying to build some UI with background-specific design and I was wondering how do you keep QLinearGradient always in the middle? If you set just a number like QLinearGradient(0, 0, 700, 0) it will remain in the same spot even if a window will be resized, which is not desired...

Here is test code:

from PySide2.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit, QApplication
from PySide2.QtGui import QLinearGradient, QPalette, QColor, QBrush
from PySide2.QtCore import Qt


    class MainWindow(QDialog):
        def __init__(self, parent=None):
            QDialog.__init__(self, parent=parent)
            self.setWindowFlags(Qt.Window)
            self.setObjectName('Test')
            self.setWindowTitle('Test')
            self.mainLayout = QVBoxLayout()
            self.find_line = QLineEdit()
            self.replace_line = QLineEdit()
            self.setLayout(self.mainLayout)
            self.rename_button = QPushButton('test button')
            self.h_layout_a = QHBoxLayout()
            law_grad_col = self.lawrencium_gradiant_color()
            self.setting_ui(set_colour=law_grad_col)
            self.create()
    
        def setting_ui(self, set_colour=None, **kwargs):
            self.setPalette(set_colour)
            self.resize(300, 50)
    
        def lawrencium_gradiant_color(self, **kwargs):
            p = QPalette()
            gradient = QLinearGradient(0, 0, 700, 0)
            gradient.setColorAt(0.0, QColor(15, 12, 41))
            gradient.setColorAt(0.5, QColor(48, 43, 99))
            gradient.setColorAt(1.0, QColor(36, 36, 62))
            p.setBrush(QPalette.Window, QBrush(gradient))
            return p
    
        def create(self, **kwargs):
            find = 'Find'
            replace = 'Replace'
            self.find_line.setPlaceholderText(find)
            self.replace_line.setPlaceholderText(replace)
            self.mainLayout.addLayout(self.h_layout_a)
            self.h_layout_a.addWidget(self.find_line)
            self.h_layout_a.addWidget(self.replace_line)
            self.h_layout_a.addWidget(self.rename_button)
    
    
    if __name__ == '__main__':
        import sys
    
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())

Solution

  • You need to use setCoordinateMode() with ObjectBoundingMode (or ObjectMode for Qt > 5.12) or StretchToDeviceMode and set coordinates in 0.0-1.0 ranges.

    gradient = QLinearGradient(0, 0, 1, 0)
    gradient.setCoordinateMode(gradient.ObjectMode)
    

    For gradients used on the whole widget, it won't change much, as the object mode is intended for individual "objects" drawn with QPainter (rectangles, ellipses, etc).