1. QScrollArea
QScrollArea 是一个带滚动条的区域,当内部的内容超过区域本身大小时会显示出滚动条
核心:当 scrollAreaWidgetContents 设置的尺寸不能容纳下内部的部件时,则会显示滚动条
核心方法:
-
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy) :设置垂直滚动策略
-
Qt::ScrollBarAsNeeded : 当内容超过显示区域时则显示滚动条 (推荐)
-
Qt::ScrollBarAlwaysOff : 永远不显示滚动条
-
Qt::ScrollBarAlwaysOn : 一直显示滚动条
-
-
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy) :设置水平滚动策略
-
setSizeAdjustPolicy() : 设置滚动条滚动策略
-
QAbstractScrollArea::AdjustIgnored : 不显示滚动条
-
QAbstractScrollArea::AdjustToContents : 根据内容调整是否有滚动条 (推荐)
-
示例:
cpp
ui->scrollArea->setFixedSize(131, 150);
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
ui->scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
代码方式:
-
创建 scrollArea 对象(滚动区域),并设置大小、位置
-
创建一个空的 QWidget
-
创建一个水平布局或者垂直布局,并加到 QWidget 当中
-
向水平布局或者垂直布局中添加所需的部件
-
将 QWidget 添加到 ScrollArea 当中
cpp
// 1. 实例化滚动区域,并显示到窗口上
QScrollArea *area = new QScrollArea(this);
area->setFixedSize(180, 80);
area->move(250, 20);
// 2. 实例化一个 Widget 和 一个 垂直布局; 让垂直布局关联 Widget
QWidget *w = new QWidget;
QVBoxLayout *v = new QVBoxLayout(w);
// 3. 将所有的按钮添加到 垂直布局当中
for (int i = 1; i <= 10; i++)
{
QPushButton *btn = new QPushButton(QString("btn_%1").arg(i));
v->addWidget(btn);
}
// 4. 将Widget 添加到 滚动区域中
area->setWidget(w);
2. QTabWidget
QTabWidget:用来制作选项卡
常用方法:
-
setCurrentIndex(int index) : 设置选中的选项卡
-
setTabPosition(QTabWidget::North, South, West, East) : 设置选项卡的位置
-
setMovable(true/false) :设置选项卡是否可以移动
-
setTabsclosable(true/false) : 设置选项卡是否可以被关闭,true时显示关闭按钮
-
removeTab(index) :关闭 tab 选项卡
-
addTab(QWidget *widget, QString): 添加新的选项卡
信号:
-
currentChanged(int index) : 点击选项卡触发,获取当前选项卡的索引号
-
tabBarClicked(int index) : 点击选项卡触发,获取当前选项卡的索引号
-
tabBarDoubleClicked(int index) : 双击选项卡触发,获取当前选项卡的索引号
-
tabCloseRequested(int index) : 点击关闭按钮时触发,获取当前选项卡的索引号
示例:
cpp
// 设置 tabWidget 各种属性
ui->tabWidget->setCurrentIndex(2);
ui->tabWidget->setMovable(true);
ui->tabWidget->setTabPosition(QTabWidget::North);
ui->tabWidget->setTabsClosable(true);
// 添加新选项卡
QWidget *w = new QWidget;
QVBoxLayout *v = new QVBoxLayout(w);
ui->tabWidget->addTab(w, "其他");
v->addWidget(new QLabel("羽毛球还是一如既往的nb"));
v->addWidget(new QLabel("跳水还是一如既往的nb"));
cpp
// 移除选中的选项卡
void Widget::on_tabWidget_tabCloseRequested(int index)
{
ui->tabWidget->removeTab(index);
}
void Widget::on_tabWidget_currentChanged(int index)
{
qDebug() << index;
}
void Widget::on_tabWidget_tabBarClicked(int index)
{
qDebug() << "tabBar" << index;
}
void Widget::on_tabWidget_tabBarDoubleClicked(int index)
{
qDebug() << "tabBar-Double" << index;
}
3. QStackedWidget
QStackedWidget :
-
count() :获取 stacked 长度
-
setCurrentIndex(index) : 设置显示第几页
-
addWidget(*widget) : 向最后添加新页
-
insertWidget(index, *widget) : 在指定位置添加新页
-
currentWidget(*widget) : 获取当前页对象
-
removeWidget(*widget) : 移除指定页
cpp
ui->stackedWidget->setCurrentIndex(this->index);
// 添加新页
QWidget *w = new QWidget;
QVBoxLayout *v = new QVBoxLayout(w);
v->addWidget(new QLabel("aaa"));
v->addWidget(new QLabel("bbb"));
v->addWidget(new QLabel("ccc"));
ui->stackedWidget->addWidget(w);
// 上一页
connect(ui->prevBtn, &QPushButton::clicked, [this](){
this->index = --this->index < 0 ? 0 : this->index;
ui->stackedWidget->setCurrentIndex(this->index);
});
// 下一页
connect(ui->nextBtn, &QPushButton::clicked, [this](){
this->index = ++this->index == 3 ? 2 : this->index;
ui->stackedWidget->setCurrentIndex(this->index);
});
// 移除当前页
connect(ui->removeBtn, &QPushButton::clicked, [=](){
ui->stackedWidget->removeWidget(ui->stackedWidget->currentWidget());
});
4. QToolBox
addItem() : 向toolbox中添加一个新的分组
用户数据初始化:
cpp
/ 单条用户信息结构
struct UserStruct
{
int id;
QString username;
QString userImg;
};
// 用户组数据结构
struct FriendListStruct
{
QString group;
QVector<UserStruct> userList;
};
// 用户数据
QVector<FriendListStruct> firendList;
this->firendList = {
{"艾欧尼亚", {
{1, "阿狸", ":/images/Ahri"},
{2, "贾克斯", ":/images/jax"},
{3, "亚索", ":/images/Yasou"},
{4, "易大师", ":/images/yi"}
}},
{"诺克萨斯", {
{5, "德莱厄斯", ":/images/Darius"},
{6, "卡特", ":/images/kate"},
{7, "瑞文", ":/images/Riven"}
}},
{"德玛西亚", {
{8, "赵信", ":/images/Zhaoxin"},
{9, "薇恩", ":/images/vn"},
{10, "娑娜", ":/images/Sona"}
}}
};
cpp
// 创建 QToolBox
QToolBox *friendBox = new QToolBox(this);
friendBox->setFixedSize(150, 400);
friendBox->move(200, 30);
friendBox->setFrameShape(QFrame::Box);
// 遍历数据, 得到阵营名称
for (auto val : this->firendList)
{
// 创建一个空的 Widget
QWidget *w = new QWidget;
w->setFont(QFont("微软雅黑", 12));
// 遍历用户信息
for (int i = 0; i < val.userList.size(); i++)
{
// 创建单个用户按钮
UserStruct tmp = val.userList.at(i);
QToolButton *userBtn = new QToolButton;
userBtn->resize(150, 50);
userBtn->setText(tmp.username);
userBtn->setIcon(QIcon(tmp.userImg));
userBtn->setIconSize(QSize(20, 20));
userBtn->move(0, i * 50);
userBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
userBtn->setParent(w);
}
// 将阵营列表添加到 ToolBox 中
friendBox->addItem(w, val.group);
}
5. QListWidget
-
QListWidget 用来设置列表
-
addItem : 向列表中添加选项,选项必须是 QListWidgetItem 类型
-
insertItem(int row, QListWidgetItem *item) : 在 row 后添加一行
-
setAlternatingRowColors: 设置颜色是否交替
-
setViewMode: 设置列表显示模式
- QListView::ListMode (列表模式) | QListView::IconMode (图标模式)
-
-
QListWidgetItem 用来设置列表中的选项
- setTextAlignment 用来设置文本对齐方式
-
信号:
-
itemClicked(QListWidgetItem *item) : 单击选中某个选项时触发,参数为当前选中项对象
-
itemDoubleClicked(QListWidgetItem *item) : 双击选中某个选项时触发
-
currentRowChanged(int currentRow) :单击选中某个选项时触发,参数为当前选项的索引号
-
cpp
struct HeroStruct
{
int id;
QString heroName;
QString imgPath;
};
QVector<HeroStruct> heroList;
this->heroList = {
{1, "艾希", ":/images/ashe"},
{2, "贾克斯", ":/images/jax"},
{3, "薇恩", ":/images/vn"},
{4, "格雷福斯", ":/images/Graves"},
{5, "卡特", ":/images/kate"}
};
cpp
ui->listWidget->setAlternatingRowColors(true);
// 遍历数据
for (int i = 0; i < heroList.size(); i++)
{
HeroStruct tmp = this->heroList.at(i);
// 创建数据项
QListWidgetItem *item = new QListWidgetItem;
item->setIcon(QIcon(tmp.imgPath));
item->setText(tmp.heroName);
ui->heroList->addItem(item);
}
// itemClicked 信号在选中某个选项时触发
// 参数:选中项对象
void Widget::on_listWidget_itemClicked(QListWidgetItem *item)
{
qDebug() << item->text();
}
// currentRowChanged 信号在选中某个选项时触发
void Widget::on_listWidget_currentRowChanged(int currentRow)
{
qDebug() << "currentRowChanged" << currentRow;
}
// 设置显示方式
void Widget::on_listRadio_clicked()
{
ui->heroList->setViewMode(QListView::ListMode);
}
void Widget::on_iconRadio_clicked()
{
ui->heroList->setViewMode(QListView::IconMode);
}
6. QTreeWidget
-
QTreeWidget : 用来设置树形菜单
-
setHeaderLabels : 设置头部
-
addTopLevelItem: 添加顶级节点
-
-
QTreeWidgetItem : 用来设置树形菜单的项
- addChild: 添加子节点
示例1: 带表头的树形菜单
cpp
// TreeWidget (带表头的树形菜单)
QStringList labels = {"英雄类型", "英雄介绍"};
ui->treeWidget->setHeaderLabels(labels);
// 添加一级菜单(顶级菜单)
QTreeWidgetItem *p = new QTreeWidgetItem({"力量"});
ui->treeWidget->addTopLevelItem(p);
QTreeWidgetItem *m = new QTreeWidgetItem({"敏捷"});
ui->treeWidget->addTopLevelItem(m);
QTreeWidgetItem *z = new QTreeWidgetItem({"智力"});
ui->treeWidget->addTopLevelItem(z);
// 添加二级菜单
QTreeWidgetItem *niutou = new QTreeWidgetItem({"牛头酋长", "长得像牛的力量型英雄"});
p->addChild(niutou);
QTreeWidgetItem *shanqiu = new QTreeWidgetItem({"山丘之王", "会扔锤子的力量型英雄"});
p->addChild(shanqiu);
QTreeWidgetItem *js = new QTreeWidgetItem({"剑圣", "拿把大刀乱砍的敏捷型英雄"});
m->addChild(js);
QTreeWidgetItem *emo = new QTreeWidgetItem({"恶魔猎手", "拿把水果刀乱砍的敏捷型英雄"});
m->addChild(emo);
QTreeWidgetItem *fs = new QTreeWidgetItem({"大法师", "骑着马到处乱跑的法师"});
z->addChild(fs);
QTreeWidgetItem *xz = new QTreeWidgetItem({"先知", "会放电的法师"});
z->addChild(xz);
示例2: 不带表头的树形菜单
cpp
// 不带表头的树形菜单
ui->deptWidget->setHeaderHidden(true);
// 创建一级节点
QTreeWidgetItem *s = new QTreeWidgetItem(ui->deptWidget);
s->setText(0, "销售部");
s->setCheckState(0, Qt::Unchecked);
ui->deptWidget->addTopLevelItem(s);
QTreeWidgetItem *t = new QTreeWidgetItem(ui->deptWidget);
t->setText(0, "技术部");
t->setCheckState(0, Qt::Unchecked);
ui->deptWidget->addTopLevelItem(t);
QTreeWidgetItem *h = new QTreeWidgetItem(ui->deptWidget);
h->setText(0, "人事行政部");
h->setCheckState(0, Qt::Unchecked);
ui->deptWidget->addTopLevelItem(h);
// 创建二级节点
QTreeWidgetItem *t1 = new QTreeWidgetItem(t);
t1->setText(0, "研发部");
t1->setCheckState(0, Qt::Checked);
QTreeWidgetItem *t2 = new QTreeWidgetItem(t);
t2->setText(0, "测试部");
t2->setCheckState(0, Qt::Checked);
QTreeWidgetItem *t3 = new QTreeWidgetItem(t);
t3->setText(0, "运维部");
t3->setCheckState(0, Qt::Checked);
QTreeWidgetItem *h1 = new QTreeWidgetItem;
h1->setText(0, "人事部");
h1->setCheckState(0, Qt::Checked);
h->addChild(h1);
QTreeWidgetItem *h2 = new QTreeWidgetItem;
h2->setText(0, "行政部");
h2->setCheckState(0, Qt::Checked);
h->addChild(h2);
// 添加三级菜单
QTreeWidgetItem *h22 = new QTreeWidgetItem;
h22->setText(0, "行政一部");
h22->setCheckState(0, Qt::Checked);
h2->addChild(h22);
// 所有子菜单全部展开
ui->deptWidget->expandAll();
信号: itemClicked() : 点击任何节点时触发
cpp
void Widget::on_deptWidget_itemClicked(QTreeWidgetItem *item, int column)
{
qDebug() << item->text(0);
}
cpp
this->deptList = {
{1, "销售部", "卖东西的部门", 0, 0},
{2, "技术部", "搞技术的部门", 0, 0},
{3, "人事财务部", "搞人的部门", 0, 0},
{4, "销售一部", "销售一部", 1, 0},
{5, "销售二部", "销售二部", 1, 0},
{6, "研发部", "搞项目开发的部门", 2, 0},
{7, "测试部", "搞项目测试的部门", 2, 0},
{8, "运维部", "搞项目运维的部门", 2, 0},
{9, "人事部", "招人的部门", 3, 0},
{10, "财务部", "发工资的部门", 3, 0}
};
for (auto val : this->deptList)
{
if (val.pid == 0)
{
QTreeWidgetItem *t = new QTreeWidgetItem(ui->deptTree);
t->setText(0, val.deptName);
t->setText(1, val.deptDesc);
t->setCheckState(0, Qt::Unchecked);
for (auto v : this->deptList)
{
if (val.id == v.pid)
{
QTreeWidgetItem *sub = new QTreeWidgetItem(t);
sub->setText(0, v.deptName);
sub->setText(1, v.deptDesc);
sub->setCheckState(0, Qt::Unchecked);
t->addChild(sub);
}
}
ui->deptTree->addTopLevelItem(t);
}
}
7. QTableWidget
-
QTableWidget : 设置表格
-
setColumnCount(int num) : 设置总列数
-
setRowCount(int num) : 设置行数
-
setHorizontalHeaderLabels(QStringList label): 设置表头
-
setItem(行号,列号,数据项) : 设置单元格数据
-
-
QTableWidgetItem: 设置单元格内容
cpp
heroList = {
{"张飞", 28, 1},
{"孙尚香", 18, 0},
{"貂蝉", 20, 0},
{"吕布", 35, 1}
};
// 设置表格
// 设置列数
ui->tableWidget->setColumnCount(3);
// 设置表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "姓名" << "年龄" << "性别");
// {"姓名", "年龄", "性别"}
// 设置行数
ui->tableWidget->setRowCount(5);
// 设置表格数据
ui->tableWidget->setItem(0, 0, new QTableWidgetItem("关羽"));
ui->tableWidget->setItem(0, 1, new QTableWidgetItem("50"));
ui->tableWidget->setItem(0, 2, new QTableWidgetItem("男"));
for(int i = 0; i < heroList.size(); i++)
{
ui->tableWidget->setItem(i + 1, 0, new QTableWidgetItem(heroList[i].name));
ui->tableWidget->setItem(i + 1, 1, new QTableWidgetItem(QString::number(heroList[i].age)));
ui->tableWidget->setItem(i + 1, 2, new QTableWidgetItem(heroList[i].gender == 1 ? "男" : "女"));
}
8. 右键菜单
窗口以及容器都能添加右键菜单
信号:
- customContextMenuRequested() : 右键菜单信号
方法:
-
setContextMenuPolicy() : 设置右键菜单模式
-
currentRow() : 获取当前选中的行号
-
currentItem() : 获取当前选中的行对象
-
insertItem(int index, QListWidgetItem *item) : 向list指定位置插入新选项
-
removeItemWidget(QListWidgetItem *item) : 移除选中项
-
clear() : 清空列表
示例1: 为 listWidget 添加右键菜单
cpp
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
// 设置右键菜单显示
ui->heroList->setContextMenuPolicy(Qt::CustomContextMenu);
// 右键菜单
this->menu = new QMenu;
this->addAction = this->menu->addAction("插入");
this->delAction = this->menu->addAction("删除");
this->clsAction = this->menu->addAction("清空");
connect(this->addAction, &QAction::triggered, [this](){
qDebug() << "插入";
int i = ui->heroList->currentRow();
ui->heroList->insertItem(i + 1, new QListWidgetItem("new Item"));
});
connect(this->delAction, &QAction::triggered, [this](){
qDebug() << "删除";
QListWidgetItem *item = ui->heroList->currentItem();
ui->heroList->removeItemWidget(item);
delete item;
});
connect(this->clsAction, &QAction::triggered, [this](){
qDebug() << "清空";
ui->heroList->clear();
});
}
// 鼠标右键触发菜单
void Widget::on_heroList_customContextMenuRequested(const QPoint &pos)
{
this->menu->exec(QCursor::pos());
}
示例2: 为窗口增加右键菜单
cpp
// 配置窗口的右键策略
this->setContextMenuPolicy(Qt::CustomContextMenu);
// 窗口右键菜单
// 一级菜单
this->winMenu = new QMenu;
this->winMenu->addAction("撤销");
this->winMenu->addSeparator();
this->winMenu->addAction("复制");
this->winMenu->addAction("粘贴");
// 二级菜单
QMenu *l2 = new QMenu("新建");
this->winMenu->addMenu(l2);
l2->addAction("文件夹");
l2->addAction("文本文档");