pythonpyqt4qtoolbutton

display two color font on QToolButton


I want a button that shows a text with two colors. I've tried the following:

import sys
from PyQt4 import QtCore,QtGui


class Example(QtGui.QWidget):
    
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()


    def clicked(self,name):
        self.drop_btns_hide(self.dropdown)
        print("Clicked on {}".format(name))        
        
        
    def initUI(self):
        
        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
        self.phslst = ['abc','def','ghi','jkl']
        
        self.setToolTip('This is a <b>QWidget</b> widget')
         
        btn = QtGui.QToolButton(self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')        
        btn.resize(btn.sizeHint())
        btn.move(50, 50)       
        text = QtGui.QTextDocument()
        text.setHtml('<b>'
                     '<font color="#0085C8" size="6" face="Avenir">'
                     'Select Phase'
                     '</font>'
                     '<font color="#d8d8d8" size="6">'
                     '&#9660;'
                     '</font>'
                     '</b>')
        pixmap = QtGui.QPixmap(text.size().width(), text.size().height())
        pixmap.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(pixmap)
        text.drawContents(painter, QtCore.QRectF(pixmap.rect()))
        icon = QtGui.QIcon(pixmap)
        self.select_icon = icon
        btn.setIcon(icon)
        btn.setIconSize(pixmap.size())        
        
        btnA = QtGui.QPushButton('Test', self)
        btnA.setToolTip('This is a <b>QPushButton</b> widget')
        btnA.resize(btnA.sizeHint())
        btnA.move(10, 100)
        
        self.setGeometry(300, 300, 250, 250)
        self.setWindowTitle('Tooltips')    
        self.show()

        
def main():
    
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

but I'm getting:

QPaintDevice: Cannot destroy paint device that is being painted
fish: “python QToolButton.py” terminated by signal SIGSEGV (Address boundary error)

and I don't understand why.


Solution

  • The QPainter methods are not executed immediately since for efficiency reasons what these methods do is accumulate instructions. And that's what happens in your case since the QPainter is still active and has the property of the QPixmap, that's why you get that error, so in this case the solution is to invoke the end() method:

    text = QtGui.QTextDocument()
    text.setHtml('<b>'
                 '<font color="#0085C8" size="6" face="Avenir">'
                 'Select Phase'
                 '</font>'
                 '<font color="#d8d8d8" size="6">'
                 '&#9660;'
                 '</font>'
                 '</b>')
    
    pixmap = QtGui.QPixmap(text.size().toSize())
    pixmap.fill(QtCore.Qt.transparent)
    
    painter = QtGui.QPainter(pixmap)
    text.drawContents(painter, QtCore.QRectF(pixmap.rect()))
    painter.end() # <-- this line
    
    icon = QtGui.QIcon(pixmap)
    btn.setIcon(icon)
    btn.setIconSize(pixmap.size())