Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QComboBox Custom Paint Event Flickering Issue
Forum Update on Monday, May 27th 2025

QComboBox Custom Paint Event Flickering Issue

Scheduled Pinned Locked Moved Unsolved Qt for Python
3 Posts 1 Posters 349 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • EmrecpE Offline
    EmrecpE Offline
    Emrecp
    wrote on last edited by Emrecp
    #1

    Hello,
    I am trying to create custom combobox.
    Code:

    # -*- coding: utf-8 -*-
    import sys, os, time
    from PySide6 import QtCore, QtWidgets, QtGui
    from PySide6.QtWidgets import *
    from PySide6.QtCore import *
    from PySide6.QtGui import *
    
    
    class EComboBoxData(object):
        Radius = 15
        AnimationTime = 600  # ms
        FontSize, FontSpacing = 16, 0
        Color = {
            "CORNER": QColor(214, 214, 216),
            "BASE_BACKGROUND": QColor(247, 247, 250),
            "BASE_FOREGROUND": QColor(255, 152, 91),
    
            "BASE_HOVER_BACKGROUND" :QColor(255, 152, 91),
            "BASE_HOVER_FOREGROUND": QColor(247, 247, 250),
    
        }
        TextElide = Qt.ElideMiddle
    
    
    class CustomComboDelegate(QStyledItemDelegate):
        ComboBoxData = EComboBoxData()
        def __init__(self, ComboBoxData,parent=None):
            super(CustomComboDelegate, self).__init__(parent)
            self.ComboBoxData = ComboBoxData
            self.text_default = self.ComboBoxData.Color["BASE_FOREGROUND"]#QColor(199, 199, 199)
            self.text_hover = QColor.red#QColor(255, 255, 255)
            self.cell_default = self.ComboBoxData.Color["BASE_BACKGROUND"]#QColor(67, 67, 67)
            self.cell_hover = QColor(43, 43, 43)
    
    
        def paint(self, painter, option, index):
            painter.save()
            painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
            value = index.data(QtCore.Qt.DisplayRole)
            painter.setFont(self.parent().font())
            painter.fillRect(option.rect, self.cell_default)
            painter.setPen(QPen(self.ComboBoxData.Color["BASE_HOVER_BACKGROUND"],1))
    
            painter.drawText(option.rect, QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, value)
            if option.state & QStyle.State_MouseOver:
                painter.setBrush(self.ComboBoxData.Color["BASE_HOVER_BACKGROUND"])
                painter.drawRect(option.rect.adjusted(0,1,0,1))
                #painter.drawRoundedRect(option.rect, self.ComboBoxData.Radius, self.ComboBoxData.Radius)
                painter.setPen(QPen(self.ComboBoxData.Color["BASE_HOVER_FOREGROUND"],1))
                painter.drawText(option.rect, QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, value)
            painter.restore()
    
    class EComboBox(QComboBox):
        ComboBoxData = EComboBoxData()
        PrivateData = {
            "ShowPopup" : False
        }
        def __init__(self, ComboBoxData=EComboBoxData()):
            super(EComboBox, self).__init__(None)
            self.ComboBoxData = ComboBoxData
            self.setItemDelegate(CustomComboDelegate(ComboBoxData, self))
            self.setMinimumHeight(34)
            self._animation = QtCore.QPropertyAnimation(self, b"_vallll", duration=self.ComboBoxData.AnimationTime)
            #id = QFontDatabase.addApplicationFont(r"C:\Users\Emre\Desktop\img\Font\Baloo2-Bold.ttf");id2 = QFontDatabase.addApplicationFont(r"C:\Users\Emre\Desktop\img\Font\Fredoka-Bold.ttf")
            #fontadi = QFontDatabase.applicationFontFamilies(id);fontadi2 = QFontDatabase.applicationFontFamilies(id2)
    
            self.myfont = QFont("Times New Roman", 16, weight=QFont.Bold)#QFont(fontadi[0], 16, weight=QFont.Bold)
            self.myfont.setWordSpacing(self.ComboBoxData.FontSpacing)
            self.myfont.setStyleHint(QFont.Monospace)
            self.myfontMetrics = QFontMetrics(self.myfont)
            # font.setStyleHint(QFont.Times, QFont.PreferAntialias)
            self.setFont(self.myfont)
            self.setMinimumWidth(150)
            effect = QtWidgets.QGraphicsOpacityEffect(self.model(), opacity=1.0)
            self.setGraphicsEffect(effect)
            self._animation = QtCore.QPropertyAnimation(
                self.model(),
                propertyName=b"opacity",
                targetObject=effect,
                duration=500,
                startValue=0.0,
                endValue=1.0,
            )
    
            self._animation.setDirection(QtCore.QPropertyAnimation.Forward)
            #self._animation.start()
    
    
    
        #_vallll = QtCore.Property(int, fget=value, fset=ESetValue, notify=valueChanged)
    
        def showPopup(self) -> None:
            #self.PrivateData["ShowPopup"] = True
            #self._animation.start()
            QComboBox.showPopup(self)
        def hidePopup2(self) -> None:
            self.PrivateData["ShowPopup"] = False
        def paintEvent(self, event: QPaintEvent) -> None:
            pt = QPainter(self)
            pt.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing )
            border = QPainterPath()
            border.addRoundedRect(QRectF(self.rect().adjusted(2, 2, -3, -3)),self.ComboBoxData.Radius, self.ComboBoxData.Radius)
    
    
            pt.setPen(QPen(self.ComboBoxData.Color['CORNER'], 3.5))
            pt.setBrush(self.ComboBoxData.Color['BASE_BACKGROUND'])
    
            pt.drawPath(border)
    
            pt.setClipPath(border)
    
    
    
    
            pen = QPen(QColor(QtCore.Qt.black))
            #pen.setWidth(10)
            brush = QBrush(pen.color().darker(150))
            pt.setBrush(brush)
    
    
    
            w, h = self.width(), self.height()
            arrow_width, arrow_height = 12, 20
            arrow_margin_width, arrow_margin_height = 16, 14
            arrowBodyPoints= QPoint()
            pt.setPen(QPen(self.ComboBoxData.Color['CORNER'], 3));
    
            pt.setBrush(Qt.NoBrush)
            path2 = QPainterPath()
            path2.addPolygon(QPolygonF(
                [QPoint(w-arrow_margin_width-arrow_width, arrow_margin_height),QPoint(w-arrow_margin_width- (arrow_width/2),arrow_height),
                 QPoint(w - arrow_margin_width - (arrow_width / 2),arrow_height), QPoint(w-arrow_margin_width,arrow_margin_height)
    
                 ]))
            pt.drawPath(path2)
            pt.setPen(self.ComboBoxData.Color["BASE_FOREGROUND"])
            pt.setFont(self.myfont)
            TextRect = self.rect().adjusted(4,0, -arrow_width-arrow_margin_width-2,0)
            Text = self.myfontMetrics.elidedText(self.currentText(), self.ComboBoxData.TextElide, TextRect.width())
            pt.drawText(TextRect, Qt.AlignCenter, Text)
    
    
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        wind = QMainWindow()
        wind.setStyleSheet("QMainWindow{background-color:blue}")
        wind.setWindowTitle("EComboBox")
        wind.resize(221, 150)
        wid = QWidget()
        lay = QHBoxLayout(wid)
        lay.setAlignment(Qt.AlignCenter)
        
        Data = EComboBoxData()
        e = EComboBox(Data)
        e.addItems([ "Uzun bir yazı 123","Otomatik", "1 MB/sn", "5 MB/sn", "8 MB/sn"])
       
       
        lay.addWidget(e)
        wind.setCentralWidget(wid)
        wind.show()
        sys.exit(app.exec())
    

    When click combobox for see items; It flickers.
    Video: Flickering
    Thanks!

    1 Reply Last reply
    0
    • EmrecpE Offline
      EmrecpE Offline
      Emrecp
      wrote on last edited by Emrecp
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • EmrecpE Offline
        EmrecpE Offline
        Emrecp
        wrote on last edited by
        #3

        Note: PySide6 Version: 6.2.2.1

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved