2.8 输入控件(三)
2.8.5 QComboBox 下拉框
QComboBox提供了一个选项列表,这样就可以占用最少的屏幕空间。
image.png1 count: 下拉列表中的条目总个数
2 currentData:当前item中存储的数据。
这个属性很重要,当你的每个item想要和某个对象进行关联时,为每个item设置它的存储数据是非常明智的,一般情况会有两种做法,一种是将当前对象id或指针存起来,一种是将整个对象存到itemData中。这里小豆君推荐第一种写法,不理解的可以看我待会儿给出的示例。
3 currentIndex:当前选择的条目索引。
无论是否以编程方式或用户交互方式更改当前选项,下拉框都发出currentIndexChanged(),而activated()只在由用户交互引起的更改时发出。当用户在combobox弹出列表中高亮显示某个项时,会发出highlighted()信号。这三个信号都有两个版本,一个是QString参数,另一个是int参数。
4 duplicatesEnabled:新增条目是否可重复。
5 editable:是否可编辑。
如果是可编辑的,那么会有以下设置:
- 允许用户修改列表中的每个项目,并且调用clearEditText(),可清除显示的字符串,而不改变combobox的内容。如果你是调用的clear(),那么所有条目都会被清除。
- 新输入的字符串也可以插入到列表中,并且可以选择插入的位置。默认策略是插入到最末端,但可以使用setInsertPolicy()来更改这个插入策略。
- 使用setValidator()可以设置验证器。
- 调用setCompleter()设置记忆或联想功能。
关于验证器和联想记忆功能,已经在QLineEdit中已经讲过了,忘记的同学可以再去看一下。
6 insertPolicy:插入模式。
- QComboBox::NoInsert:不能插入。
- QComboBox::InsertAtTop:插入到最上边。
- QComboBox::InsertAtCurrent:替换当前的item文字。
- QComboBox::InsertAtBottom:插入到最后。
- QComboBox::InsertAfterCurrent:在当前item之后插入。
- QComboBox::InsertBeforeCurrent:在当前Item之前插入。
- QComboBox::InsertAlphabetically:按字幕顺序插入。
7 maxCount:列表允许可添加条目的最大个数。
如果你将最大数量设置为小于当前combobox中的条目数量,则额外的条目将被截断。
8 maxVisibleItems:最大可显示条目个数。
如果你的条目有很多时,你可以设置下拉列表中最多可显示的条目个数。
QComboBox其实也用到了MVC框架,这部分内容等讲到MVC时,再具体介绍。
2.8.6 示例
在上一节的InputWidget类中,继续添加代码。
在ui界面中插入一个tab页,标签设置为QComboBox
ui界面:
image.png下面只列出新增的代码
inputwidget.h 头文件包含 #include <QHash>
class Student
{
public:
Student()
{
m_age = 0;
}
bool isValid() const
{
return !id().isEmpty();
}
QString id() const {return m_id;}
void setId(const QString &id) {m_id = id;}
QString name() const{return m_name;}
void setName(const QString &name){m_name = name;}
uint age() const{return m_age;}
void setAge(uint age){m_age = age;}
QString getDisplayText() const
{
QString ret;
if (isValid())
{
ret = QString("姓名:%1\n年龄:%2").arg(name()).arg(age());
}
return ret;
}
private:
QString m_id;
QString m_name;
uint m_age;
};
class InputWidget : public QWidget
{
Q_OBJECT
private slots:
//QComboBox
void on_combo_student_activated(int index);
void on_combo_insertPolicy_currentIndexChanged(int index);
void on_check_editable_toggled(bool checked);
void on_check_duplicatesEnabled_toggled(bool checked);
void on_spinBox_maxCount_valueChanged(int arg1);
void on_spinBox_maxVisibleItems_valueChanged(int arg1);
private:
void initLineEditTab();
void initTextEditTab();
void initComboBoxTab();
Student addStudent();
void showStudent(int index);
bool hasAddStudentItem();
private:
QHash<QString, Student> m_studentHash;//用来保存学生信息,key-id,value-学生类
};
inputwidget.cpp 构造函数添加initLineEditTab();
void InputWidget::initComboBoxTab()
{
//插入模式
QStringList textList;
textList << "NoInsert" <<"InsertAtTop" << "InsertAtCurrent" << "InsertAtBottom"
<< "InsertAfterCurrent" << "InsertBeforeCurrent" << "InsertAlphabetically";
ui->combo_insertPolicy->addItems(textList);
}
Student InputWidget::addStudent()
{
Student stu;
QString text = ui->combo_student->currentText();
QStringList textList = text.split(",");
if (textList.size() == 2)
{
bool ok;
QString name = textList.at(0);
uint age = textList.at(1).toUInt(&ok);
if (ok)
{
//为每个学生创建唯一id
stu.setId(QUuid::createUuid().toString());
stu.setName(name);
stu.setAge(age);
m_studentHash.insert(stu.id(), stu);
}
}
return stu;
}
void InputWidget::showStudent(int index)
{
QString id = ui->combo_student->itemData(index).toString();
Student stu = m_studentHash.value(id);
if (stu.isValid())
{
ui->label_student->setText(stu.getDisplayText());
}
}
bool InputWidget::hasAddStudentItem()
{
return m_studentHash.size() < ui->combo_student->count();
}
void InputWidget::on_combo_student_activated(int index)
{
if (hasAddStudentItem())//判断是否已经添加了学生item,此时的item并不一定合法,若不合法则要删除
{
Student stu = addStudent();
if (stu.isValid())//如果输入正确,则添加学生条目
{
ui->combo_student->setItemData(index, stu.id());
}
else//如果是输入错误,则删除新增的item,并提示
{
ui->combo_student->removeItem(index);
QMessageBox::information(this,
tr("录入学生信息"),
tr("输入错误,请重新输入,格式为:“姓名,年龄”。回车确认。"),
"好滴");
}
}
showStudent(index);
}
void InputWidget::on_combo_insertPolicy_currentIndexChanged(int index)
{
ui->combo_student->setInsertPolicy((QComboBox::InsertPolicy)index);
}
void InputWidget::on_check_editable_toggled(bool checked)
{
ui->combo_student->setEditable(checked);
if (checked)
ui->combo_student->setEditText("录入格式:姓名,年龄");
}
void InputWidget::on_check_duplicatesEnabled_toggled(bool checked)
{
ui->combo_student->setDuplicatesEnabled(checked);
}
void InputWidget::on_spinBox_maxCount_valueChanged(int arg1)
{
ui->combo_student->setMaxCount(arg1);
}
void InputWidget::on_spinBox_maxVisibleItems_valueChanged(int arg1)
{
ui->combo_student->setMaxVisibleItems(arg1);
}
编译运行程序
勾选editable复选框,选择插入策略,然后按照格式输入学生信息,并回车,如果输入正确的话,会在右侧的学生信息标签中显示刚刚的输入信息。
好了,关于QComboBox的内容今天先讲到这里。
欢迎关注小豆君的微信公众号:小豆君,只要关注,便可加入我的C++\Qt交流群一起学习。