文章目录
前言
上一篇文章讲了怎么给textedit加上灰色提示作为一种compeleter
但有很大的局限性,比如只能提供一个词,很多时候输完词也没用上Tab补词,显然这个模块更适合于有AI补充句子功能的编辑器。
所以我还是回到用Qcompleter完成功能。
但原版的QCompleter真的太丑了!
于是就有了这篇文章。
完整代码效果图
下面主要分为三个模块
一是我的尝试过程,包括遇到的一些问题及解决方法
二是QCompleter的设计注意点
三是完整代码
文章目录
一、尝试过程
第一版代码:全部使用stylesheet完成
想要实现的效果应该是
- 文本框样式
- 输入字符提示在选中的选项部分应该为灰色背景
没达到预期效果
还有为了应对背景莫名奇妙出现的白色方框,出现将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的整体样式。
如果对你有帮助,请帮忙点个赞收个藏❤