补全ScorllArea代码逻辑
我们将其他ListItem项目全部设置成和基本设置一样的代码,唯独不一样的就是把题头的label修改成对应的文本,例如基本设置,云盘设置等。
Widget对应一个类
每一个Widget创建对应的类,头文件和cpp文件,里面的代码和CBaseSetWidget类代码类似。
唯一不一样的就是把题头的Text文本修改成对应的文本。
主Widget中定义每个类的指针对应一个widget
定义存储widget指针的vector
在主widget中定义全局变量vector存储widget指针。
将各个widget创建并添加到ScorllArea
QWidget* pWidget = new QWidget;
QVBoxLayout* pVLayout = new QVBoxLayout(pWidget);
m_pBaseSetWidget = new CBaseSetWidget;
m_pYunpanSetWidget = new CYunPanSetWidget;
m_pDownloadWidget = new CDownloadWidget;
m_pJieguanWidget = new CJieguanWidget;
m_pRenwuWidget = new CRenwuWidget;
m_pTixingWidget = new CTixingWidget;
m_pXuanfuWidget = new CXuanfuWidget;
m_pGaoJiWidget = new CGaojiWidget;
m_vecWidget.push_back(m_pBaseSetWidget);
m_vecWidget.push_back(m_pYunpanSetWidget);
m_vecWidget.push_back(m_pDownloadWidget);
m_vecWidget.push_back(m_pJieguanWidget);
m_vecWidget.push_back(m_pRenwuWidget);
m_vecWidget.push_back(m_pTixingWidget);
m_vecWidget.push_back(m_pXuanfuWidget);
m_vecWidget.push_back(m_pGaoJiWidget);
pVLayout->addWidget(m_pBaseSetWidget);
pVLayout->addWidget(m_pYunpanSetWidget);
pVLayout->addWidget(m_pDownloadWidget);
pVLayout->addWidget(m_pJieguanWidget);
pVLayout->addWidget(m_pRenwuWidget);
pVLayout->addWidget(m_pTixingWidget);
pVLayout->addWidget(m_pXuanfuWidget);
pVLayout->addWidget(m_pGaoJiWidget);
m_pScrollArea->setWidget(pWidget);
widget的继承应用
QWidget* pWidget = new QWidget;
QVBoxLayout* pVLayout = new QVBoxLayout(pWidget);
首先我们创建一个pwidget,将各个widget整合成这一个pwidget最后只需要将ScorllArea设置成这个整体pwidget即可。
1. QWidget* pWidget = new QWidget;
- 这是一个普通的 QWidget,它作为容器,用来容纳其他控件。您可以将它看作是一个空的窗口或区域,可以添加其他控件和布局。
2. QVBoxLayout* pVLayout = new QVBoxLayout(pWidget);
- 这是一个垂直布局管理器 (
QVBoxLayout
)。 pVLayout
是指向QVBoxLayout
的指针,它将控件垂直堆叠在一起(从上到下)。pWidget
被作为布局的父对象,所有控件都将在pWidget
内按垂直顺序排列。
此时我们只需要填写pVLayout
控件即可,pVLayout
控件会自动添加到pWidget
。
ListWidget与ScorllArea信号联动
connect(m_pListWidget, &QListWidget::itemClicked, this, &demo14_ScorllArea::slotItemClicked);
connect(m_pScrollArea->verticalScrollBar(), &QScrollBar::valueChanged,
this, &demo14_ScorllArea::slotValueChanged);
这段代码使用了 Qt 信号与槽机制,将控件的某些事件(比如 QListWidget
的 item 点击和 QScrollBar
的滚动条值变化)与特定的槽函数(处理程序)关联起来。
1. connect(m_pListWidget, &QListWidget::itemClicked, this, &demo14_ScorllArea::slotItemClicked);
m_pListWidget
是指向QListWidget
的指针。itemClicked
是QListWidget
的一个信号,表示列表中的某一项被点击时触发。this
是当前对象(通常是一个类的实例,demo14_ScorllArea
)。slotItemClicked
是槽函数,当列表中的一项被点击时,它会被调用。该函数通常会处理与点击事件相关的逻辑。
2. connect(m_pScrollArea->verticalScrollBar(), &QScrollBar::valueChanged, this, &demo14_ScorllArea::slotValueChanged);
m_pScrollArea->verticalScrollBar()
获取QScrollArea
中的垂直滚动条。valueChanged
是滚动条的信号,当滚动条的值发生变化时触发。滚动条的值对应于当前滚动的进度。slotValueChanged
是槽函数,当滚动条的值变化时调用,通常用来同步其他控件的状态或者执行滚动相关的操作。
总结:
- 当用户点击
QListWidget
中的某个项时,slotItemClicked
函数将会被调用。 - 当
QScrollArea
的滚动条滚动时,slotValueChanged
函数将会响应这个变化并处理相关逻辑。
ListWidget与ScorllArea联动的槽函数编写
void demo14_ScorllArea::slotItemClicked(QListWidgetItem* item) {
signFlag = true;
QString itemText = item->text();
QPoint widgetPos;
int size = m_textList.size();
for (int i = 0; i < size; i++) {
if (itemText == m_textList[i]) {
widgetPos = m_vecWidget[i]->pos();
}
}
m_pScrollArea->verticalScrollBar()->setValue(widgetPos.y());
}
void demo14_ScorllArea::slotValueChanged(int value) {
if (!signFlag) {
int itemSize = m_vecWidget.size();
for (int i = 0; i < itemSize; i++) {
if (!m_vecWidget[i]->visibleRegion().isEmpty()) {
m_pListWidget->item(i)->setSelected(true);
return;
} else {
m_pListWidget->item(i)->setSelected(false);
}
}
}
signFlag = false;
}
这段代码通过实现两个槽函数,完成了 QListWidget
与 QScrollArea
之间的联动。当用户点击 QListWidget
的项目时,滚动区域会自动滚动到对应的内容。当用户手动滚动时,列表中的项目会自动选中与当前可见内容相关的项目。
ListWidget中itemClicked信号会传递选中的item给槽函数
1. slotItemClicked(QListWidgetItem* item)
这个槽函数在用户点击 QListWidget
中的某个项目时被触发。
signFlag = true;
:设置标记,用于防止滚动条值变化时引发的多余操作(防止递归触发slotValueChanged
)。itemText = item->text();
:获取被点击的QListWidgetItem
的文本。- 遍历
m_textList
,找到点击的项目对应的m_vecWidget
中的控件,并获取该控件的位置(widgetPos
)。 m_pScrollArea->verticalScrollBar()->setValue(widgetPos.y());
:根据找到的控件的位置,将滚动条的值设置为该控件的垂直坐标,进而让QScrollArea
滚动到该控件的位置。
示例:
void demo14_ScorllArea::slotItemClicked(QListWidgetItem* item) {
signFlag = true;
QString itemText = item->text(); // 获取被点击的项目文本
QPoint widgetPos;
// 遍历找到与 itemText 匹配的控件
int size = m_textList.size();
for (int i = 0; i < size; i++) {
if (itemText == m_textList[i]) {
widgetPos = m_vecWidget[i]->pos(); // 获取控件的位置
}
}
// 设置滚动条的值,让 QScrollArea 滚动到控件位置
m_pScrollArea->verticalScrollBar()->setValue(widgetPos.y());
}
2. slotValueChanged(int value)
这个槽函数在 QScrollArea
的垂直滚动条值发生变化时被触发。
- 首先检查
signFlag
,确保该变化不是由点击事件引发的滚动。 - 遍历
m_vecWidget
,检查哪些控件的可见区域非空(即可见),并选中与之对应的QListWidgetItem
。 m_pListWidget->item(i)->setSelected(true);
:选中对应的列表项。signFlag = false;
:重置signFlag
,允许下一次点击或滚动正常触发。
示例:
void demo14_ScorllArea::slotValueChanged(int value) {
if (!signFlag) {
int itemSize = m_vecWidget.size();
for (int i = 0; i < itemSize; i++) {
if (!m_vecWidget[i]->visibleRegion().isEmpty()) { // 检查控件是否可见
m_pListWidget->item(i)->setSelected(true); // 选中对应的列表项
return;
} else {
m_pListWidget->item(i)->setSelected(false); // 取消其他项目的选中状态
}
}
}
signFlag = false;
}
关键点:
-
signFlag
的作用:- 通过
signFlag
来避免由于点击列表项导致的滚动和由于滚动引发的列表项选中产生的递归触发。 - 当点击列表项时,
signFlag
被设为true
,这确保slotValueChanged
不会在滚动条值变化时立即处理。
- 通过
-
m_vecWidget
和m_textList
:m_vecWidget
是与QListWidget
的项目相对应的QWidget
对象的容器(通常是控件的指针数组)。m_textList
是存储QListWidget
项目文本的列表,确保能根据点击的项目找到对应的QWidget
。
功能总结:
- 当用户点击
QListWidget
的某个项目时,slotItemClicked
会让QScrollArea
自动滚动到与该项目相关的内容。 - 当用户手动滚动
QScrollArea
时,slotValueChanged
会自动更新QListWidget
的选中项,保持列表与内容同步。
结尾
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!