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

相关推荐
&岁月不待人&19 分钟前
Kotlin by lazy和lateinit的使用及区别
android·开发语言·kotlin
StayInLove22 分钟前
G1垃圾回收器日志详解
java·开发语言
无尽的大道30 分钟前
Java字符串深度解析:String的实现、常量池与性能优化
java·开发语言·性能优化
爱吃生蚝的于勒33 分钟前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
binishuaio43 分钟前
Java 第11天 (git版本控制器基础用法)
java·开发语言·git
zz.YE1 小时前
【Java SE】StringBuffer
java·开发语言
就是有点傻1 小时前
WPF中的依赖属性
开发语言·wpf
洋2401 小时前
C语言常用标准库函数
c语言·开发语言
进击的六角龙1 小时前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式