- void TaskMgrQt::InitTreeWidget()
- {
- ui.treeWidget->header()->setVisible(false);
- ui.treeWidget->setAttribute(Qt::WA_DeleteOnClose); // QWidget 及其 派生类的对象 自动内存清理
- }
-
-
- // 进程结构体
- struct Process {
- int pid; // 进程ID
- int ppid; // 父进程ID
- QString name; // 进程名称
- std::vector
children; // 子进程数组 -
- Process(int pid, int ppid, QString name) : pid(pid), ppid(ppid), name(name) {}
- };
-
-
- // 构建进程树
- void buildProcessTree(const std::vector
int , int, QString>>& processes, std::vector& roots) { - std::vector
().swap(roots); - std::unordered_map<int, Process*> processMap;
-
- // 创建所有进程节点
- for (const auto& p : processes) {
- Process* proc = new Process(std::get<0>(p), std::get<1>(p), std::get<2>(p));
- processMap.emplace(proc->pid, proc); // 添加
- }
-
- // 将进程组织成树形结构
- for (auto& pair : processMap) {
- Process* proc = pair.second;
-
- if (proc->pid == 0)
- {
- roots.push_back(proc);
- }
- else
- {
- auto iter = processMap.find(proc->ppid);
- if (iter != processMap.end())
- {
- Process* parent = iter->second;
- if (parent) {
- parent->children.push_back(proc);
- }
- }
- else
- {
- // 顶层进程,父进程已经终止
- roots.push_back(proc);
- }
- }
- }
- }
-
-
- // 递归填充QTreeWidget
- void fillTreeWidget(QTreeWidget* treeWidget, QTreeWidgetItem* parentItem, Process* process) {
- // 创建当前进程节点
- QTreeWidgetItem* item;
-
- if (parentItem == NULL)
- {
- item = new QTreeWidgetItem(treeWidget);
- item->setText(0, QString("%1: %2").arg(process->pid).arg(process->name));
- treeWidget->addTopLevelItem(item);
- }
- else
- {
- item = new QTreeWidgetItem(parentItem);
- item->setText(0, QString("%1: %2").arg(process->pid).arg(process->name));
- }
-
- if (process->children.size() > 0)
- item->setExpanded(true);
-
- // 递归填充子进程节点
- for (Process* child : process->children) {
- fillTreeWidget(treeWidget, item, child);
- }
- }
-
-
- void TaskMgrQt::slot_onRefresh(... ...)
- {
- ... ...
-
- // 清理树控件
- ui.treeWidget->clear();
-
- // 生成树控件
- std::vector
int, int, QString>> processes; -
- for (int i = 0; i < info.list.size();)
- {
- QString qstrProcName = Ansi2Unicode(info.list[i], m_nCodePage);
- i++;
- std::string strPid = info.list[i];
- i++;
- std::string strPPID = info.list[i];
- i++;
- std::string strIs32 = info.list[i];
- i++;
-
- int nPid = atoi(strPid.c_str());
- int nPPid = atoi(strPPID.c_str());
-
- processes.push_back(std::make_tuple(nPid, nPPid, qstrProcName));
- }
-
- std::vector
roots; - buildProcessTree(processes, roots);
-
- // 填充 树控件
- for (int i = 0; i < roots.size(); i++)
- {
- fillTreeWidget(ui.treeWidget, NULL, roots[i]);
- }
-
- ... ...
- }
- void TaskMgrQt::slot_onTreeItemClick(QTreeWidgetItem* item, int column)
- {
- QString qstrItemText = item->text(column);
- QStringList qstrList = qstrItemText.split(":");
- QString qstrPid = qstrList[0].trimmed();
-
- for (int i = 0; i < ui.tableWidget->rowCount(); i++)
- {
- QString temp = ui.tableWidget->item(i, 1)->text().trimmed();
- if (temp == qstrPid)
- {
- ui.tableWidget->selectRow(i);
- break;
- }
- }
- }
- void SearchTreeWidget(QTreeWidget* treeWidget, QTreeWidgetItem* parentItem, QString qstrPid)
- {
- // 获取当前进程结点
- QString qstrTemp = parentItem->text(0).trimmed();
- QStringList qstrList = qstrTemp.split(":");
- QString qstrTempPid = qstrList[0].trimmed();
-
- if (qstrTempPid == qstrPid)
- {
- // 已遍历到 指定进程
- treeWidget->clearSelection(); // 清除之前的选择
- parentItem->setSelected(true); // 选中该项目
- treeWidget->scrollToItem(parentItem); // 确保选中项目可见
- }
-
- for (int i = 0; i < parentItem->childCount(); i++)
- {
- QTreeWidgetItem* item = parentItem->child(i);
-
- SearchTreeWidget(treeWidget, item, qstrPid);
- }
- }
-
- void TaskMgrQt::slot_onTableItemClick(QTableWidgetItem* item)
- {
- QString qstrPid = ui.tableWidget->item(item->row(), 1)->text().trimmed();
-
- for (int i = 0; i < ui.treeWidget->topLevelItemCount(); i++)
- {
- QTreeWidgetItem* item = ui.treeWidget->topLevelItem(i);
- SearchTreeWidget(ui.treeWidget, item, qstrPid);
- }
- }
注意:
在 进程树 和 进程表格 两个控件中,控件中的行数是相同的,也就是说 “控件中的行数是所有进程数目总和”。