qt通过QComboBox实现文本框自动记忆、补全和下拉选项填写

前言

在公司工作过程中,我多次遇到一个文本框经常要输入一大串信息,每次输入容易出错且速度很慢。于是我想到了QQ登录界面的功能。

image-20220817141532798

QQ登录界面的基本功能为:当点击下拉框,会出现曾经登录过的有效的账号密码,且排在前面的为最新登录过的账号,当输入曾经登录过的账号的前几位时,会自动补全。我觉得这种输入就非常的人性化,于是打算常用的输入框都使用这种思路。


在qt中,使用QComboBox去替代QLineEdit,将QComboBox改为可编辑,这样既拥有了输入框又有下拉框。QComboBox还会在输入信息的时候进行自动补全。自动记忆功能我们通过读写配置文件来实现。

image-20220817142819087

image-20220817143007154

实现思路

通过QStringList来存储名字信息,下拉列表中默认显示QStringList中第一个名字,当选择QStringList中已存的一个名字时,(在触发事件触发后)会将这个名字放到QStringList的开头(这样QStringList中记录的顺序其实就是使用过的顺序了),当在文本框中输入新的名字时,会将新名字添加到QStringList开头。


大致思路我觉得不是很难,直接上代码

.h文件(这里面只是定义了几个全局变量)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSettings>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QSettings *m_IniFile;
    QStringList m_usernameList;
};
#endif // MAINWINDOW_H

.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QCompleter>
#include <QSettings>
#include <QDebug>
#include <QTextCodec>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString exePath=QCoreApplication::applicationDirPath();
    //配置文件为可执行程序所在的目录下的local.ini
    QString iniFile=exePath+"/local.ini";

    //m_IniFile为全局变量QSettings *m_IniFile;
    m_IniFile = new QSettings(iniFile, QSettings::IniFormat,this);
    //文件中的编码要设置和这里对应,比如我都设置成UTF-8
    m_IniFile->setIniCodec(QTextCodec::codecForName("UTF-8"));

    //通过Value函数将节下相对应的键值读取出来
    QString username =m_IniFile->value("client/username").toString();

    m_usernameList=username.split("|");
    ui->comboBox->setEditable(true);
    ui->comboBox->setCurrentText(m_usernameList.at(0));
    ui->comboBox->addItems(m_usernameList);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    //我希望的是每进行一次触发事件后,这次文本框中的内容会设置成在下次打开程序时的默认值
    //只有触发事件后才进行这样的操作
    QString currentContent=ui->comboBox->currentText();
    if(m_usernameList.contains(currentContent)){
        m_usernameList.removeAt(ui->comboBox->currentIndex());
    }
    m_usernameList.push_front(currentContent);
    m_usernameList.removeAll("");
    QString username;
    for (int i=0;i<m_usernameList.size();i++ ) {
        if(i==m_usernameList.size()-1){
            username+=m_usernameList.at(i);
        }else{
            username+=m_usernameList.at(i)+"|";
        }
    }
    m_IniFile->setValue("client/username",username);
    qDebug()<<ui->comboBox->currentText();
}

如果下拉列表中存储的信息过多,我们想像浏览器那样,输入部分信息进行匹配,则只需要在构造函数中使用QCompleter即可,但注意使用这个的时候会导致下拉列表的自动补全无法使用

	//将名字列表放入QCompleter中
	QCompleter *completer = new QCompleter(m_usernameList);
    ui->comboBox->setCompleter(completer);

实现效果是这样:

image-20220817144101206

区别自动补全和智能提示,下面是自动补全的效果:

image-20220817144317297

自动补全会补全最近的一个

完成这些之后,只需要对下拉框进行美化,即可达到qq登录界面的那种效果

链接:QComboBox样式设置


其实还有一个下拉选项后面的那个删除功能没有实现,,默认QComboBox是没有删除的那个叉号的,需要自定义QComboBox类,然后增加下拉列表的删除功能,就很复杂,我这里没用到。就不进行实现了。


码字不易,如果这篇博客对你有帮助,麻烦点赞收藏,非常感谢!有不对的地方,可以评论区交流。

### 如何通过 QtQComboBox 方法实现多选功能 为了实现 `QComboBox` 多选的功能,可以通过其提供的 `setModel`、`setView` `setLineEdit` 方法来自定义控件的行为。以下是详细的实现方式: #### 1. 设置模型 (`setModel`) `QComboBox` 可以通过设置一个自定义的模型来控制数据展示的方式。通常情况下,可以使用 `QStringListModel` 或者更复杂的 `QAbstractItemModel` 来存储管理数据。 ```python from PyQt5.QtCore import QStringListModel, Qt model = QStringListModel() data_list = ["Option 1", "Option 2", "Option 3"] model.setStringList(data_list) combo_box.setModel(model) # 将模型绑定到组合框上[^1] ``` #### 2. 设置视图 (`setView`) 默认情况下,`QComboBox` 使用的是 `QListView` 来显示下拉菜单的内容。要支持多选,可以用 `QListWidget` 替代它,并允许用户选择多个项。 ```python from PyQt5.QtWidgets import QListWidget, QApplication list_widget = QListWidget() for item in data_list: list_item = f"{item}" list_widget.addItem(list_item) list_widget.setSelectionMode(QListWidget.MultiSelection) # 启用多选模式[^2] combo_box.setView(list_widget) # 绑定自定义视图到组合框上 ``` #### 3. 设置编辑器 (`setLineEdit`) 为了让用户能够看到已选中的项目,需要创建一个自定义的 `QLineEdit` 并将其与 `QComboBox` 关联起来。 ```python from PyQt5.QtWidgets import QLineEdit line_edit = QLineEdit() def update_line_edit(): selected_items = [list_widget.item(i).text() for i in range(list_widget.count()) if list_widget.item(i).isSelected()] line_edit.setText(", ".join(selected_items)) list_widget.itemSelectionChanged.connect(update_line_edit) # 当选择改变时更新文本框内容[^3] combo_box.setLineEdit(line_edit) # 将自定义编辑器绑定到组合框上 update_line_edit() # 初始化线程编辑器内容 ``` 以上代码片段展示了如何利用 `setModel`、`setView` `setLineEdit` 这三个函数构建一个多选的 `QComboBox` 控件。需要注意的是,在实际应用过程中可能还需要处理一些细节问题,比如防止不必要的信号触发或者优化用户体验等。 #### 完整示例代码 下面是一个完整的 Python 示例程序,演示了上述过程的具体实现: ```python import sys from PyQt5.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QComboBox, QListWidget, QLineEdit, ) class MultiSelectComboBox(QWidget): def __init__(self): super().__init__() layout = QVBoxLayout(self) self.combo_box = QComboBox() model = QStringListModel(["Option A", "Option B", "Option C"]) self.combo_box.setModel(model) self.list_widget = QListWidget() for option in model.stringList(): self.list_widget.addItem(option) self.list_widget.setSelectionMode(QListWidget.MultiSelection) self.combo_box.setView(self.list_widget) self.line_edit = QLineEdit() self.update_line_edit_text() self.list_widget.itemSelectionChanged.connect(self.update_line_edit_text) self.combo_box.setLineEdit(self.line_edit) layout.addWidget(self.combo_box) def update_line_edit_text(self): selections = ", ".join( [ self.list_widget.item(index).text() for index in range(self.list_widget.count()) if self.list_widget.item(index).isSelected() ] ) self.line_edit.setText(selections) if __name__ == "__main__": app = QApplication(sys.argv) window = MultiSelectComboBox() window.show() sys.exit(app.exec_()) ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值