QT windows平台下获取U盘 QComboBox显示U盘盘符

本文介绍了如何在Windows环境下使用Qt获取U盘信息,通过调用Windows API进行U盘检测,并展示了如何将U盘盘符添加到QComboBox中。代码示例包括了U盘插入和移除的事件监听以及盘符计算。
在windows平台下获取U盘信息,可以调用windows API函数比较方便。本来想用qt QDBusConnection 来写的,网上关于这方面的代码比较多,但按照提示的步骤来写的就是无法编译,我也不知道为什么。如果有知道的朋友,留言给我或者qq 1585519210联系

在windows平台下U盘检测采用windows事件来设计,废话少说,上代码!
#ifndef GETUSBDISKWIDGET_H
#define GETUSBDISKWIDGET_H

#include <QWidget>
#include <windows.h>
#include <winbase.h>
#include <winnls.h>
#include <dbt.h>
#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QVector>
#include <QStringList>

namespace Ui {
    class GetUsbDiskWidget;
}

typedef struct USB_DISK_INFO
{
    QString DirPath;
    float TotalMemory;
    float FreeMemory;
}USB_DISK_INFO;

class GetUsbDiskWidget : public QWidget
{
    Q_OBJECT

public:
    explicit GetUsbDiskWidget(QWidget *parent = 0);
    ~GetUsbDiskWidget();
    void Init();
    void ScanHD();
    void AddDisk(QString &DiskName);
    void DeleteDisk(QString &DiskName);
    bool SearchDisk(QString &DiskName,int &iter);
    void GetMemorySize(USB_DISK_INFO & disk);
    void AddComboBoxItem(QString &item);
    void DeleteComboBoxItem(QString &item);
    bool winEvent(MSG *message, long *result);
    char FirstDriveFromMask (ULONG unitmask);
    USB_DISK_INFO GetCheckedDisk();


private:
    Ui::GetUsbDiskWidget *ui;  
    QVector<USB_DISK_INFO> usb_disk_info;
    USB_DISK_INFO CurrentUseDisk;

private slots:
    void on_comboBox_USB_currentIndexChanged(QString );
};

#endif // GETUSBDISKWIDGET_H

#include "getusbdiskwidget.h"
#include "ui_getusbdiskwidget.h"
#include <QTextCodec>

GetUsbDiskWidget::GetUsbDiskWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::GetUsbDiskWidget)
{
    QText
<think>好的,我现在要解决的问题是用户在Windows平台上使用QT和C++结合winscard.h库,通过QComboBox显示读卡器名称。用户需要示例代码。首先,我需要回忆一下相关的API和步骤。 首先,winscard.h属于PC/SC标准,用于智能卡读卡器的通信。用户需要列出所有连接的读卡器名称。根据PC/SC的文档,SCardListReaders函数可以获取读卡器列表。我应该先调用SCardEstablishContext来建立上下文,这是使用其他函数的前提。 接下来,SCardListReaders的参数需要正确的上下文句柄、读者组,以及分配足够的内存来存储返回的读卡器名称字符串。记得处理返回的错误代码,比如SCARD_E_NO_READERS_AVAILABLE表示没有读卡器连接。 然后,如何将获取的读卡器名称列表填充到QComboBox中。因为返回的读卡器名称是一个多字符串,即以双空字符结尾的字符串数组,需要用循环逐个提取每个名称,并添加到QComboBox的项中。 还需要考虑内存管理,SCardListReaders返回的字符串内存需要用SCardFreeMemory释放,避免内存泄漏。同时,在QT中处理C字符串到QString的转换,可能需要用到QString::fromWCharArray或者QString::fromUtf16,因为Windows API通常返回宽字符。 另外,错误处理也很重要,比如检查每个API调用的返回值,确保操作成功。如果出现错误,可能需要显示错误信息给用户。 现在,考虑代码结构。首先在QT项目中包含winscard.h和必要的头文件,可能需要链接到WinSCard.lib。然后,在某个初始化函数里,比如窗口的构造函数中,调用上述步骤获取读卡器列表,并更新QComboBox。 可能的代码步骤: 1. 建立上下文:SCardEstablishContext。 2. 获取读卡器列表的长度:第一次调用SCardListReaders传入NULL指针获取所需缓冲区大小。 3. 分配缓冲区并再次调用SCardListReaders获取实际数据。 4. 解析多字符串,逐个添加到QComboBox。 5. 释放内存和释放上下文。 需要注意的问题包括宽字符的处理,在QT中使用QString的正确转换,以及确保在32/64位环境下的兼容性。此外,可能需要处理用户权限问题,比如以管理员权限运行程序才能访问读卡器。 最后,测试代码是否在没有读卡器的情况下正确处理,例如返回空列表,并在插入读卡器后是否需要动态刷新列表。用户可能需要手动触发刷新,或者自动检测读卡器状态的变化,这部分可能涉及更复杂的实现,但当前问题只需要静态获取读卡器名称即可。</think>以下是使用QT/C++结合winscard.h显示读卡器名称的示例代码: ```cpp #include <QtWidgets> #include <winscard.h> #include <tchar.h> void MainWindow::loadReadersToCombo(QComboBox* combo) { combo->clear(); SCARDCONTEXT hContext = 0; LPTSTR pReader = nullptr; DWORD dwReaders = 0; LONG lReturn = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hContext); if (lReturn != SCARD_S_SUCCESS) { qDebug() << "建立上下文失败:" << lReturn; return; } // 第一次调用获取缓冲区大小 lReturn = SCardListReaders(hContext, nullptr, (LPTSTR)&pReader, &dwReaders); if (lReturn == SCARD_E_NO_READERS_AVAILABLE) { qDebug() << "未检测到读卡器"; SCardReleaseContext(hContext); return; } else if (lReturn != SCARD_S_SUCCESS) { qDebug() << "获取读卡器列表失败:" << lReturn; SCardReleaseContext(hContext); return; } // 解析多字符串结构 LPTSTR p = (LPTSTR)pReader; while (*p != '\0') { QString readerName = QString::fromWCharArray(p); combo->addItem(readerName); p = p + wcslen(p) + 1; // 移动到下一个字符串 } SCardFreeMemory(hContext, pReader); SCardReleaseContext(hContext); } ``` 关键实现步骤说明: 1. **建立上下文**:使用`SCardEstablishContext`初始化PC/SC通信上下文,这是所有读卡器操作的先决条件[^1] 2. **获取读卡器列表**: - 首次调用`SCardListReaders`时传入null指针获取所需缓冲区大小 - 二次调用实际获取多字符串结构的读卡器列表 3. **解析多字符串**: - 读卡器名称以双空字符结尾的宽字符串形式返回 - 使用`QString::fromWCharArray`进行Unicode转换 4. **内存管理**: - 必须使用`SCardFreeMemory`释放分配的缓冲区 - 最后调用`SCardReleaseContext`释放上下文资源 注意事项: - 需要链接`WinSCard.lib`库(在.pro文件中添加`LIBS += -lWinSCard`) - 需要管理员权限才能访问某些读卡器设备 - 多字符串解析时需注意指针步进长度
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值