Qt获取磁盘信息+表格显示

效果展示

主要代码

获取磁盘相关数据

获取磁盘数据 Qt 没有提供相关的接口,需要使用 Windows API。接口解释如下:

cpp 复制代码
BOOL GetDiskFreeSpaceExW(
  [in, optional]  LPCWSTR         lpDirectoryName,
  [out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

[in, optional] lpDirectoryName

磁盘上的目录。

如果此参数为 NULL ,则该函数使用当前磁盘的根。

如果此参数是 UNC 名称,则必须包含尾随反斜杠,例如"\MyServer\MyShare\"。

此参数不必指定磁盘上的根目录。 函数接受磁盘上的任何目录。

调用应用程序必须对此具有 FILE_LIST_DIRECTORY 访问权限

"sample"目录中。

[out, optional] lpFreeBytesAvailableToCaller

指向变量的指针,该变量接收磁盘上可供与调用线程关联的用户使用的可用字节总数。

此参数可以为 NULL。

如果使用每用户配额,此值可能小于磁盘上的可用字节总数。

[out, optional] lpTotalNumberOfBytes

指向变量的指针,该变量接收磁盘上可供与调用线程关联的用户使用的字节总数。

此参数可以为 NULL。

如果使用每用户配额,此值可能小于磁盘上的字节总数。

若要确定磁盘或卷上的字节总数,请使用 IOCTL_DISK_GET_LENGTH_INFO

[out, optional] lpTotalNumberOfFreeBytes

指向接收磁盘上可用字节总数的变量的指针。

此参数可以为 NULL。

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零 (0)。要获得更多的错误信息,请调用 GetLastError。

在实际使用的时候,我们依然需要注意数据类型转化等问题,还需要进行一定的计算才能获得我们需要的数据:

cpp 复制代码
void DiskSizeTable::loadData()
{
    int row = this->rowCount();
    for (size_t i = 0; i < row; i++) {
        this->removeRow(0);
    }

#ifdef Q_OS_WIN
    QFileInfoList list = QDir::drives();

    foreach (QFileInfo dir, list) {
        QString dirName = dir.absolutePath();
        LPCWSTR lpcwstrDriver = (LPCWSTR)dirName.utf16();
        ULARGE_INTEGER liFreeBytesAvailable, liTotalBytes, liTotalFreeBytes;

        if (GetDiskFreeSpaceEx(lpcwstrDriver, &liFreeBytesAvailable, &liTotalBytes, &liTotalFreeBytes)) {
            QString use = QString::number((double)(liTotalBytes.QuadPart - liTotalFreeBytes.QuadPart) / GB, 'f', 1);
            use += "G";
            QString free = QString::number((double)liTotalFreeBytes.QuadPart / GB, 'f', 1);
            free += "G";
            QString all = QString::number((double)liTotalBytes.QuadPart / GB, 'f', 1);
            all += "G";
            int percent = 100 - ((double)liTotalFreeBytes.QuadPart / liTotalBytes.QuadPart) * 100;

            insertSize(dirName, use, free, all, percent);
        }
    }
#else
    process->start("df -h");

#endif
}

如果是 Windows 系统(Q_OS_WIN)的话就调用 Windows API,如果是其他的类 Unix 系统就会启动一个进程执行 df -h 命令,该命令在类 Unix 系统中用于显示文件系统的磁盘空间占用情况。这部分代码未提供处理命令输出的逻辑,但可以通过信号和槽机制或者重定向标准输出流来读取结果。

表格数据显示

我直接将重要的部分注释在代码里:

cpp 复制代码
void DiskSizeTable::insertSize(const QString &name, const QString &use, const QString &free, const QString &all, int percent)
{
    int row = this->rowCount();
    this->insertRow(row);

    QTableWidgetItem* itemname = new QTableWidgetItem(name);
    QTableWidgetItem* itemuse = new QTableWidgetItem(use);
    itemuse->setTextAlignment(Qt::AlignCenter); // 居中显示
    QTableWidgetItem* itemfree = new QTableWidgetItem(free);
    itemfree->setTextAlignment(Qt::AlignCenter);
    QTableWidgetItem* itemall = new QTableWidgetItem(all);
    itemall->setTextAlignment(Qt::AlignCenter);

    this->setItem(row, 0, itemname);
    this->setItem(row, 1, itemuse);
    this->setItem(row, 2, itemfree);
    this->setItem(row, 3, itemall);

    QProgressBar* bar = new QProgressBar;
    bar->setRange(0, 100); // 数据区间
    bar->setValue(percent);

    QString qss = QString("QProgressBar{background:%1;border-width:0px;border-radius:0px;text-align:center;}"
                          "QProgress::chunk{border-radius:0px;}").arg(bgColor.name());

// 根据使用情况来设置颜色
    if (percent < 50) {
        qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor1.name()).arg(pgrColor1.name());
    }
    else if (percent < 90) {
        qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor2.name()).arg(pgrColor2.name());
    }
    else {
        qss += QString("QProgressBar{color:%1;}QProgressBar::chunk{background:%2;}").arg(textColor3.name()).arg(pgrColor3.name());
    }

    bar->setStyleSheet(qss);
    this->setCellWidget(row, 4, bar); // 在QTableWidget中添加其他窗口
}

表格的一些设置

cpp 复制代码
this->setSelectionBehavior(QAbstractItemView::SelectRows); // 选择行为:整行
this->setEditTriggers(QAbstractItemView::NoEditTriggers); // 编辑触发:不触发(无法编辑)
this->setSelectionMode(QAbstractItemView::SingleSelection); // 选择模式:一次只能选中一行
this->verticalHeader()->setVisible(true); // 行头可见
this->horizontalHeader()->setStretchLastSection(true); // 最后一列自动伸展填充

完整代码

gitcode 链接

资料参考:https://github.com/0voice

相关推荐
侃侃_天下2 天前
最终的信号类
开发语言·c++·算法
echoarts2 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix2 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题2 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说2 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔2 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号2 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_2 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty2 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再2 天前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame