Qt QCompleter样式设计 pyqt5


前言

上一篇文章讲了怎么给textedit加上灰色提示作为一种compeleter
但有很大的局限性,比如只能提供一个词,很多时候输完词也没用上Tab补词,显然这个模块更适合于有AI补充句子功能的编辑器。
在这里插入图片描述
所以我还是回到用Qcompleter完成功能。
但原版的QCompleter真的太丑了!
于是就有了这篇文章。

完整代码效果图
在这里插入图片描述

下面主要分为三个模块
一是我的尝试过程,包括遇到的一些问题及解决方法
二是QCompleter的设计注意点
三是完整代码


一、尝试过程

第一版代码:全部使用stylesheet完成

想要实现的效果应该是

  1. 文本框样式
  2. 输入字符提示在选中的选项部分应该为灰色背景
    没达到预期效果
    还有为了应对背景莫名奇妙出现的白色方框,出现将background改为透明时整个组件变黑的情况。
    这大概是因为某个父节点的作用太大导致。
    在这里插入图片描述 在这里插入图片描述
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QCompleter, QListView

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle('QCompleter with Custom Stylesheet Example')
        layout = QVBoxLayout()
        # 创建一个 QLineEdit 对象
        self.line_edit = QLineEdit(self)
        # 设置 QLineEdit 的样式表
        self.line_edit.setStyleSheet('''
            QLineEdit {
                border: 2px solid gray;
                border-radius: 15px;
                padding: 6px;
                selection-background-color: darkgray;
                min-width: 10em;
                font: 20px;
            }
        ''')
        # 创建一个 QCompleter 对象
        completer = QCompleter(["apple", "orange", "banana", "grape", "watermelon", "pear"], self)
        completer.setCaseSensitivity(False)  # 设置大小写不敏感
        completer.setCompletionMode(QCompleter.PopupCompletion)  # 设置完成模式
        # 获取 QCompleter 的弹出视图并设置 objectName
        completer_popup = completer.popup()
        completer_popup.setObjectName("completerPopup")

        # 设置 QCompleter 弹出视图的样式表
        completer_popup.setStyleSheet('''
            QAbstractItemView#completerPopup {
                border: 2px solid rgb(81, 81, 81);
                padding: 1px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item {
                border: 2px solid rgb(81, 81, 81);
                padding-top: 2px;
                padding-bottom: 2px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item:hover {
                background-color: lightGrey;
            }
        ''')
        # 将 QCompleter 设置为 QLineEdit 的补全器
        self.line_edit.setCompleter(completer)
        # 将 QLineEdit 添加到布局中
        layout.addWidget(self.line_edit)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


第二版代码:添加popup.window()的设置

在网上多番查找,才终于在外网上的基于C++的qt才找到答案。
这是苦苦找了四个小时的网站
只要添加上下面的代码就可以去掉背景上的白框,然后就可以用Stylesheet或者QStyledItemDelegate添加上其它效果
关于QStyledItemDelegate:这是一个托管,目前我使用下来最好用的部分是可以设置文本的位置与格式

completer_popup = completer.popup()
# 设置弹出视图的属性
completer_popup.window().setWindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.NoDropShadowWindowHint) 
# 设置弹出视图的背景透明,不加则要运用sytlesheet添加颜色
completer_popup.window().setAttribute(Qt.WA_TranslucentBackground)  

Qt.Popup:

该标志表示窗口是一个弹出窗口。弹出窗口通常是短暂的对话框或菜单,会在特定事件发生时出现,并在点击窗口外部区域时自动关闭。
使用此标志的窗口具有特殊的行为,例如总是出现在前景,并且在获得焦点时可以自动关闭。
Qt.FramelessWindowHint:
该标志表示窗口没有边框,即没有标题栏和边框装饰。 使用此标志可以创建一个无框窗口,常用于自定义窗口外观,例如实现自定义标题栏或全屏窗口。
Qt.NoDropShadowWindowHint:

该标志表示窗口没有阴影效果。
默认情况下,许多操作系统在窗口周围添加阴影以增强视觉效果。使用此标志可以禁用这种阴影效果,使窗口看起来更加平坦。

下面是完整代码
我特地增加了醒目的颜色,当然也可以设置透明效果
在这里插入图片描述

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QCompleter, QStyledItemDelegate, QListView
from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtCore import Qt

class CompleterDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(CompleterDelegate, self).initStyleOption(option, index)
        # 设置文本颜色
        option.palette.setColor(QPalette.Text, QColor("black"))
        option.displayAlignment = Qt.AlignCenter

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

    def initUI(self):
        self.setStyleSheet('''
            QWidget {
                background-color: lightBlue;}''')
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle('QCompleter with Custom Delegate Example')

        layout = QVBoxLayout()

        # 创建一个 QLineEdit 对象
        self.line_edit = QLineEdit(self)

        # 设置 QLineEdit 的样式表
        self.line_edit.setStyleSheet('''
            QLineEdit {
                border: 2px solid gray;
                border-radius: 15px;
                padding: 6px;
                min-width: 10em;
                font: 20px;
            }
        ''')

        # 创建一个 QCompleter 对象
        completer = QCompleter(["an apple", "an orange", "a banana", "a grape", "a watermelon", "a pear"], self)
        completer.setCaseSensitivity(False)  # 设置大小写不敏感
        completer.setCompletionMode(QCompleter.PopupCompletion)  # 设置完成模式

        # 获取 QCompleter 的弹出视图并设置 objectName
        completer_popup = completer.popup()
        completer_popup.window().setWindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.NoDropShadowWindowHint) # 设置弹出视图的属性
        completer_popup.window().setAttribute(Qt.WA_TranslucentBackground)  # 设置弹出视图的背景透明
        completer_popup.setObjectName("completerPopup")
        # 设置 QCompleter 弹出视图的样式表
        completer_popup.setStyleSheet('''
            QAbstractItemView#completerPopup {
                background-color: white; /**设置弹出视图的背景颜色,仅在setAttribute(Qt.WA_TranslucentBackground)时生效**/
                border: 2px solid rgb(81, 81, 81);
                padding: 1px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item {
                background-color: white;  /**设置弹出视图的项目背景颜色,最主要控制**/
                border: 2px solid rgb(81, 81, 81);
                padding-top: 2px;
                padding-bottom: 2px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item:hover {
                background-color: lightGrey;
            }
        ''')

        # 设置 QCompleter 弹出视图的委托
        delegate = CompleterDelegate(self)
        completer_popup.setItemDelegate(delegate)

        # 将 QCompleter 设置为 QLineEdit 的补全器
        self.line_edit.setCompleter(completer)

        # 将 QLineEdit 添加到布局中
        layout.addWidget(self.line_edit)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


二、QCompleter设计注意点

第一步:建立QCompleter对象

# 创建一个 QCompleter 对象
completer = QCompleter(["an apple", "an orange", "a banana", "a grape", "a watermelon", "a pear"], self)
completer.setCaseSensitivity(False)  # 设置大小写不敏感
completer.setCompletionMode(QCompleter.PopupCompletion)  # 设置完成模式

# 获取 QCompleter 的弹出视图并设置 objectName
completer_popup = completer.popup()

第二步:设置QStyledItemDelegate,用其控制文本颜色与大小

建议创建一个子类

class CompleterDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(CompleterDelegate, self).initStyleOption(option, index)
        # 设置文本颜色
        option.palette.setColor(QPalette.Text, QColor("black"))
        # 设置文本大小
        option.font.setPointSize(10)
        option.displayAlignment = Qt.AlignCenter
delegate = CompleterDelegate(self)
# 添加popup的托管
completer_popup.setItemDelegate(delegate)

第三步:添加stylesheet

# 获取 QCompleter 的弹出视图并设置 objectName
completer_popup = completer.popup()
# 设置弹出视图的属性
completer_popup.window().setWindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.NoDropShadowWindowHint) 
# 设置弹出视图的背景透明,这时就算给popup颜色,依然透明
# 如果不给背景透明,可以通过stylesheet给popup颜色,否则为黑色背景
completer_popup.window().setAttribute(Qt.WA_TranslucentBackground)  
# 给popup添加属性名以给予样式
completer_popup.setObjectName("completerPopup")
# 设置 QCompleter 弹出视图的样式表
completer_popup.setStyleSheet('''
    QAbstractItemView#completerPopup {
    /**设置弹出视图的背景颜色,仅在 不给弹出视图的背景透明 时生效**/
        background-color: white; 
        border: 2px solid rgb(81, 81, 81);
        padding: 1px;
        border-radius: 15px;
    }
    QAbstractItemView#completerPopup::item {
    /**设置弹出视图的项目背景颜色,这与给不给背景透明无关**/
        background-color: white;  
        border: 2px solid rgb(81, 81, 81);
        padding-top: 2px;
        padding-bottom: 2px;
        border-radius: 15px;
    }
    QAbstractItemView#completerPopup::item:hover {
    /**设置选中时的颜色**/
        background-color: lightGrey;
    }
''')

最后

如果没有提到你想要的效果,可以在这几个部分排列组合,自行调试。


三、完整代码

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QCompleter, QStyledItemDelegate, QListView
from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtCore import Qt

class CompleterDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(CompleterDelegate, self).initStyleOption(option, index)
        # 设置文本颜色
        option.palette.setColor(QPalette.Text, QColor("black"))
        # 设置文本大小
        option.font.setPointSize(8)
        option.displayAlignment = Qt.AlignCenter

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

    def initUI(self):
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle('QCompleter with Custom Delegate Example')

        layout = QVBoxLayout()

        # 创建一个 QLineEdit 对象
        self.line_edit = QLineEdit(self)

        # 设置 QLineEdit 的样式表
        self.line_edit.setStyleSheet('''
            QLineEdit {
                border: 2px solid gray;
                border-radius: 15px;
                padding: 6px;
                min-width: 10em;
                font: 20px;
            }
        ''')

        # 创建一个 QCompleter 对象
        completer = QCompleter(["an apple", "an orange", "a banana", "a grape", "a watermelon", "a pear"], self)
        completer.setCaseSensitivity(False)  # 设置大小写不敏感
        completer.setCompletionMode(QCompleter.PopupCompletion)  # 设置完成模式

        # 获取 QCompleter 的弹出视图并设置 objectName
        completer_popup = completer.popup()
        completer_popup.window().setWindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.NoDropShadowWindowHint) # 设置弹出视图的属性
        completer_popup.window().setAttribute(Qt.WA_TranslucentBackground)  # 设置弹出视图的背景透明
        completer_popup.setObjectName("completerPopup")
        # 设置 QCompleter 弹出视图的样式表
        completer_popup.setStyleSheet('''
            QAbstractItemView#completerPopup {
                background-color: white; /**设置弹出视图的背景颜色,仅在setAttribute(Qt.WA_TranslucentBackground)时生效**/
                border: 2px solid rgb(81, 81, 81);
                padding: 1px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item {
                background-color: white;  /**设置弹出视图的项目背景颜色,最主要控制**/
                border: 2px solid rgb(81, 81, 81);
                padding-top: 2px;
                padding-bottom: 2px;
                border-radius: 15px;
            }
            QAbstractItemView#completerPopup::item:hover {
                background-color: lightGrey;
            }
        ''')

        # 设置 QCompleter 弹出视图的委托
        delegate = CompleterDelegate(self)
        completer_popup.setItemDelegate(delegate)

        # 将 QCompleter 设置为 QLineEdit 的补全器
        self.line_edit.setCompleter(completer)

        # 将 QLineEdit 添加到布局中
        layout.addWidget(self.line_edit)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

总结

到这里,就可以实现QCompleter的整体样式。
如果对你有帮助,请帮忙点个赞收个藏❤

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值