一半君的总结纸

听话只听一半君

如何给QLineEdit填加搜索图标和清除内容的按钮

lineedit是最经常用到的基本控件之一,lz想把他弄的好看点. 目标效果:

  • 首先第一步当然是找个搜索图标,比如这个

    png pixmap

    from PyQt4 import QtGui, QtCore
    import sys
    
    # http://stackoverflow.com/a/12468386/2052889
    class ButtonLineEdit(QtGui.QLineEdit):
    
        def __init__(self, icon_file, parent=None):
            super(ButtonLineEdit, self).__init__(parent)
    
            self.button = QtGui.QToolButton(self)
            self.button.setIcon(QtGui.QIcon(icon_file))
            self.button.setStyleSheet('border: 0px; padding: 0px;')
            self.button.setCursor(QtCore.Qt.ArrowCursor)
    
            frameWidth = self.style().pixelMetric(
                QtGui.QStyle.PM_DefaultFrameWidth)
            buttonSize = self.button.sizeHint()
    
            self.setStyleSheet(
                'QLineEdit {padding-right: %dpx; }' % (buttonSize.width() + frameWidth + 1))
            self.setMinimumSize(max(self.minimumSizeHint().width(), buttonSize.width() + frameWidth*2 + 2),
                                max(self.minimumSizeHint().height(), buttonSize.height() + frameWidth*2 + 2))
    
            self.button.clicked.connect(self.buttonClicked)
    
        def resizeEvent(self, event):
            buttonSize = self.button.sizeHint()
            frameWidth = self.style().pixelMetric(
                QtGui.QStyle.PM_DefaultFrameWidth)
            self.button.move(self.rect().right() - frameWidth - buttonSize.width(),
                             (self.rect().bottom() - buttonSize.height() + 1)/2)
            super(ButtonLineEdit, self).resizeEvent(event)
    
        def buttonClicked(self):
            print 'You clicked the button!'
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        win = ButtonLineEdit('search.png')
        win.show()
        sys.exit(app.exec_())
    
    

    但是有时候,你可能不想存一个图片文件在外面,此时可以使用base64 encoded image, 比如

    from PyQt4 import Qt,QtGui,QtCore
    import base64
    
    # "b64_data" is a variable containing your base64 encoded jpeg
    b64_data='iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAz0lEQVQ4ja3SPUoEQRTE8R+DwcQbi/HiGTaewLMYzS1kQRAx9AB6jp1wowFPIBgabjgmNbgf0+Mu+IcHTXdVvUd380uNFlvsUtvs1f7gBj0GdHhIddnro5mkjuAbDZbpOtLkrC9N0qZLg3t84elI00TTmmCbUZcxXxcm7aI9oMItNrjDOz4LAZtoD7jaWz8WjLNU+MDqDO0q2hP2L7HE7CUeP+OUeXzGRaY+4dyP9IbXUsjcV17EPKSKISWqmAb/HPJ8ScBUyO7SgDHkJeb1DzfURQMGQROeAAAAAElFTkSuQmCC'
    
    app = QtGui.QApplication([])
    btn = QtGui.QToolButton()
    pm = QtGui.QPixmap()
    pm.loadFromData(base64.b64decode(b64_data))
    btn.setIcon(QtGui.QIcon(pm))
    btn.resize(100,100)
    btn.show()
    app.exec_()
    

    另一种方法,不使用base64

    from PyQt4 import Qt,QtGui,QtCore
    
    # "b64_data" is a variable containing your base64 encoded jpeg
    b64_data='iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAz0lEQVQ4ja3SPUoEQRTE8R+DwcQbi/HiGTaewLMYzS1kQRAx9AB6jp1wowFPIBgabjgmNbgf0+Mu+IcHTXdVvUd380uNFlvsUtvs1f7gBj0GdHhIddnro5mkjuAbDZbpOtLkrC9N0qZLg3t84elI00TTmmCbUZcxXxcm7aI9oMItNrjDOz4LAZtoD7jaWz8WjLNU+MDqDO0q2hP2L7HE7CUeP+OUeXzGRaY+4dyP9IbXUsjcV17EPKSKISWqmAb/HPJ8ScBUyO7SgDHkJeb1DzfURQMGQROeAAAAAElFTkSuQmCC'
    
    app = QtGui.QApplication([])
    btn = QtGui.QToolButton()
    pm = QtGui.QPixmap()
    data = QtCore.QByteArray.fromBase64(b64_data)
    pm.loadFromData(data)
    btn.setIcon(QtGui.QIcon(pm))
    btn.resize(100,100)
    btn.show()
    app.exec_()
    
  • 其次是要把文本输入区域用css改成圆形的,测试效果如下

    null

    from PyQt4 import QtGui, QtCore
    import sys
    
    
    class MyLineEdit(QtGui.QLineEdit):
    
        def __init__(self, parent=None):
            super(MyLineEdit, self).__init__(parent)
    
            self.setStyleSheet('''
                QLineEdit{
                    border: 2px solid gray;
                    border-radius: 12px;
                }
                ''')
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        win = QtGui.QWidget()
        layout = QtGui.QVBoxLayout(win)
    
        lineedit = MyLineEdit()
        layout.addWidget(lineedit)
        win.setLayout(layout)
        win.show()
        sys.exit(app.exec_())
    
  • 然后测试在lineedit左侧绘制按钮

    from PyQt4 import QtGui, QtCore
    import sys
    
    
    class MyLineEdit(QtGui.QLineEdit):
    
        def __init__(self, parent=None):
            super(MyLineEdit, self).__init__(parent)
    
            b64_data = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAz0lEQVQ4ja3SPUoEQRTE8R+DwcQbi/HiGTaewLMYzS1kQRAx9AB6jp1wowFPIBgabjgmNbgf0+Mu+IcHTXdVvUd380uNFlvsUtvs1f7gBj0GdHhIddnro5mkjuAbDZbpOtLkrC9N0qZLg3t84elI00TTmmCbUZcxXxcm7aI9oMItNrjDOz4LAZtoD7jaWz8WjLNU+MDqDO0q2hP2L7HE7CUeP+OUeXzGRaY+4dyP9IbXUsjcV17EPKSKISWqmAb/HPJ8ScBUyO7SgDHkJeb1DzfURQMGQROeAAAAAElFTkSuQmCC'
            data = QtCore.QByteArray.fromBase64(b64_data)
            self.searchButtonPixmap = QtGui.QPixmap()
            self.searchButtonPixmap.loadFromData(data)
    
            self.setStyleSheet('''
                                QLineEdit{
                                    padding-left: %dpx;
                                }
                               ''' % (self.searchButtonPixmap.width() + 2)
                               )
    
        def paintEvent(self, event):
            super(MyLineEdit, self).paintEvent(event)
    
            painter = QtGui.QPainter(self)
            h = self.searchButtonPixmap.height()
            right_border = 3
            painter.drawPixmap(
                right_border+2, (self.height()-h)/2, self.searchButtonPixmap)
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        w = MyLineEdit()
        w.show()
        sys.exit(app.exec_())
    

删除图标lz使用的是这个

综合上述所有效果,最后得到

import sys
from PyQt4 import QtGui, QtCore

class SearchLineEdit(QtGui.QLineEdit):

    def __init__(self,  parent=None):
        super(SearchLineEdit, self).__init__(parent)

        b64_data = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAz0lEQVQ4ja3SPUoEQRTE8R+DwcQbi/HiGTaewLMYzS1kQRAx9AB6jp1wowFPIBgabjgmNbgf0+Mu+IcHTXdVvUd380uNFlvsUtvs1f7gBj0GdHhIddnro5mkjuAbDZbpOtLkrC9N0qZLg3t84elI00TTmmCbUZcxXxcm7aI9oMItNrjDOz4LAZtoD7jaWz8WjLNU+MDqDO0q2hP2L7HE7CUeP+OUeXzGRaY+4dyP9IbXUsjcV17EPKSKISWqmAb/HPJ8ScBUyO7SgDHkJeb1DzfURQMGQROeAAAAAElFTkSuQmCC'
        data = QtCore.QByteArray.fromBase64(b64_data)
        self.searchButtonPixmap = QtGui.QPixmap()
        self.searchButtonPixmap.loadFromData(data)

        b64_data = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwklEQVQ4jXXTQYhNYRQH8N97Jkk2IyRJL2PhvaVkMdl8NAs73ctkMVlYiIVm+SZFKbMYGxRZSikp90t2SJelWciCuZNihMZkIStZTRb3e7recOpu7nf+55z//39Oy1CEEDbhGCbQ2Tw6Ch/wFA+KGH8289tD4Cks4TYO4Hv6xnEH7/Msm2xiWg3wLM7jCfplWb5uJuZZth9zOIQLRYyXYV2j81Vcw8myLL8OU6uqarnX7d7FVvR73W5VVdXbVuK8hFc4Upbl6jB4aJI2nmEvxkYwiS1p7NWUcB8rmC5iXM2zbAbHcbiI8UeeZX28xNERtdrvGpzXo6d2YiTPss+YxRdsSDnz+ISJNjpYHIxYxPgLAQs40wCHIsaVlCNhOn/Z2CjyDY8av56rd2FNtNNDb0ioGcykzguYws2kjzzLJBE/ttUbtieEsK+h8tnB2A06p7Az9RjHLjxuhRA2qm18g4nkxI5EZTkV3YZOEeN8avACuzHWghDCCdzDDUz/bxcS+BZOIy9ijM1VvohLSbA+5suyHAAHY8/hIPpFjFdo3EIqMonr2K72eTFdYy/xX8a5ItY+rimQimxA5t/n/DDtyZ/4DUr2o9PRIDtUAAAAAElFTkSuQmCC'

        data = QtCore.QByteArray.fromBase64(b64_data)
        self.clearButtonPixmap = QtGui.QPixmap()
        self.clearButtonPixmap.loadFromData(data)

        self.clearButton = QtGui.QToolButton(self)
        self.clearButton.setIcon(QtGui.QIcon(self.clearButtonPixmap))
        self.clearButton.setStyleSheet('border: 0px; padding: 0px;')
        self.clearButton.setCursor(QtCore.Qt.ArrowCursor)

        frameWidth = self.style().pixelMetric(
            QtGui.QStyle.PM_DefaultFrameWidth)

        clearButtonSize = self.clearButton.sizeHint()

        self.setMinimumSize(max(self.minimumSizeHint().width(), clearButtonSize.width() + frameWidth*2 + 2),
                            max(self.minimumSizeHint().height(), clearButtonSize.height() + frameWidth*2 + 2))

        self.setStyleSheet('''
                            QLineEdit{
                                border: 2px solid gray;
                                border-radius: 12px;
                                padding-right: %dpx;
                                padding-left: %dpx;
                            }
                           ''' % (clearButtonSize.width() + frameWidth + 2,
                                  self.searchButtonPixmap.width() +
                                  frameWidth + 2
                                  )
                           )

        self.clearButton.setVisible(False)
        self.clearButton.clicked.connect(self.clearButtonClicked)

        self.textChanged.connect(self.__updateClearButton)

    def resizeEvent(self, event):
        buttonSize = self.clearButton.sizeHint()
        frameWidth = self.style().pixelMetric(
            QtGui.QStyle.PM_DefaultFrameWidth)
        self.clearButton.move(self.rect().right() - frameWidth - buttonSize.width(),
                              (self.rect().bottom() - buttonSize.height() + 1)/2)
        super(SearchLineEdit, self).resizeEvent(event)

    def __updateClearButton(self):
            self.clearButton.setVisible(bool(self.text()))

    def clearButtonClicked(self):
        self.clear()

    def paintEvent(self, event):
        super(SearchLineEdit, self).paintEvent(event)

        painter = QtGui.QPainter(self)
        h = self.searchButtonPixmap.height()
        right_border = 3
        painter.drawPixmap(
            right_border+2, (self.height()-h)/2, self.searchButtonPixmap)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = SearchLineEdit()
    win.show()
    sys.exit(app.exec_())

参考:
How to do – inside in QlineEdit insert the button.[pyqt4]
QLineEdit with custom button
Displaying an embedded image on PyQt?

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: