首先,代码里面很详细
解读,可以学习相关你的B站课程。
CMakeLists.txt文件
cmake_minimum_required(VERSION 3.5)
project(cleess01 VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
set(PROJECT_SOURCES
main.cpp
widget.cpp
widget.h
widget.ui
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(cleess01
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET cleess01 APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(cleess01 SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(cleess01
${PROJECT_SOURCES}
)
endif()
endif()
target_link_libraries(cleess01 PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
set_target_properties(cleess01 PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(cleess01)
endif()
之后的是自定义
widget.h文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTreeWidgetItem>//自行
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
//自行定义
void InitUi();
void UpdateParentItem(QTreeWidgetItem *item);
public slots:
void TreeItemChanged(QTreeWidgetItem *item,int colum);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
main.cpp主文件
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.ui如图,比较简单,几乎用不到。。底层都可以修改的
最最最重要的文件在此。诸多函数功能模块都在这里实现的
widget.cpp文件
widget.cpp文件
#include "widget.h"
#include "./ui_widget.h"
#include <QTreeWidgetItem>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("排行榜");
QStringList str1;
str1<<"name";
ui->treeWidget->setHeaderLabels(str1);//注意加SSSS
//初始化Widget
InitUi();
connect(ui->treeWidget,SIGNAL(itemChanged(QTreeWidgetItem*,int)),this,SLOT(TreeItemChanged(QTreeWidgetItem*,int)));
}
Widget::~Widget()
{
delete ui;
}
//自行定义
void Widget::InitUi()
{
ui->treeWidget->clear();//细心一个字母都是bug
//num1
QTreeWidgetItem *group1=new QTreeWidgetItem(ui->treeWidget);
group1->setText(0,"排行榜1");
group1->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
group1->setCheckState(0,Qt::Unchecked);
QTreeWidgetItem *SubItem1=new QTreeWidgetItem(group1);
SubItem1->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
SubItem1->setText(0,"班级1");
SubItem1->setCheckState(0,Qt::Unchecked);
QTreeWidgetItem *SubItem11=new QTreeWidgetItem(group1);
SubItem11->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
SubItem11->setText(0,"班级11");
SubItem11->setCheckState(0,Qt::Unchecked);
//num2
QTreeWidgetItem *group2=new QTreeWidgetItem(ui->treeWidget);
group2->setText(0,"排行榜2");
group2->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
group2->setCheckState(0,Qt::Unchecked);
QTreeWidgetItem *SubItem2=new QTreeWidgetItem(group2);
SubItem2->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
SubItem2->setText(0,"班级02");
SubItem2->setCheckState(0,Qt::Unchecked);
QTreeWidgetItem *SubItem22=new QTreeWidgetItem(group2);
SubItem22->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
SubItem22->setText(0,"班级22");
SubItem22->setCheckState(0,Qt::Unchecked);
QTreeWidgetItem *SubItem222=new QTreeWidgetItem(group2);
SubItem222->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
SubItem222->setText(0,"班级23");
SubItem222->setCheckState(0,Qt::Unchecked);
}
void Widget::UpdateParentItem(QTreeWidgetItem *item)
{
QTreeWidgetItem *parent=item->parent();
if(parent==NULL)
return;
//选中节点个数
int selectCount=0;
int childCount=parent->childCount();
for(int i=0;i<childCount;i++)
{
QTreeWidgetItem *childItem=parent->child(i);
if(childItem->checkState(0)==Qt::Checked)
{
selectCount++;
}
}
if(selectCount<=0)
{
parent->setCheckState(0,Qt::Unchecked);//选中状态
}
else if(selectCount>0 && selectCount<childCount)
{
parent->setCheckState(0,Qt::PartiallyChecked);
}
else if(selectCount==childCount)
{
parent->setCheckState(0,Qt::Checked);
}
}
void Widget::TreeItemChanged(QTreeWidgetItem *item,int colum)
{
QString itemText=item->text(0);
//https://www.bilibili.com/video/BV1TL4y1b7a1?p=13&t=1206.2
if(Qt::Checked==item->checkState(0))
{
QTreeWidgetItem *parent=item->parent();
int count=item->childCount();
if(count>0)
{
for(int i=0;i<count;i++)
{
//子节点选中
item->child(i)->setCheckState(0,Qt::Checked);
}
}
else
{
//子节点
UpdateParentItem(item);
}
}
else if(Qt::Unchecked==item->checkState(0))
{
int count=item->childCount();
if(count>0)
{
for(int i=0;i<count;i++)
{
//子节点选中
item->child(i)->setCheckState(0,Qt::Checked);
}
}
else
{
UpdateParentItem(item);
}
}
}
运行结果