ZBLOG

qt检查打印机是否连接,usb ,windows

使用Qt在Windows下检测USB打印机连接

在Windows系统中,你可以通过以下几种方式使用Qt来检测USB打印机是否连接:

方法1:使用Windows打印API(推荐)

#include <windows.h>
#include <winspool.h>
#include <QDebug>

bool isUsbPrinterConnected(const QString& printerName = "")
{
    DWORD needed = 0, returned = 0;
    
    // 第一次调用获取所需缓冲区大小
    EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, 
                NULL, 
                2, 
                NULL, 
                0, 
                &needed, 
                &returned);
    
    if (needed == 0) {
        qDebug() << "No printers found";
        return false;
    }
    
    BYTE* buffer = new BYTE[needed];
    
    // 第二次调用获取实际打印机信息
    if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
                     NULL,
                     2,
                     buffer,
                     needed,
                     &needed,
                     &returned)) {
        delete[] buffer;
        qDebug() << "Failed to enumerate printers";
        return false;
    }
    
    PRINTER_INFO_2* printerInfo = (PRINTER_INFO_2*)buffer;
    
    for (DWORD i = 0; i < returned; ++i) {
        QString currentPrinterName = QString::fromWCharArray(printerInfo[i].pPrinterName);
        QString portName = QString::fromWCharArray(printerInfo[i].pPortName);
        
        // 检查是否是USB打印机(端口名通常包含"USB")
        bool isUsbPrinter = portName.contains("USB", Qt::CaseInsensitive);
        
        // 如果指定了打印机名称,则检查名称是否匹配
        if (!printerName.isEmpty()) {
            if (currentPrinterName.compare(printerName, Qt::CaseInsensitive) == 0 && isUsbPrinter) {
                delete[] buffer;
                return true;
            }
        } else if (isUsbPrinter) {
            // 没有指定打印机名称,只检查是否是USB打印机
            delete[] buffer;
            return true;
        }
    }
    
    delete[] buffer;
    return false;
}

方法2:使用Qt的QPrinterInfo类(有限支持)

#include <QPrinterInfo>
#include <QDebug>

bool checkForUsbPrinter(const QString& printerName = "")
{
    QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
    
    foreach(const QPrinterInfo &printer, printers) {
        qDebug() << "Found printer:" << printer.printerName();
        
        // Windows下可能无法直接判断是否为USB打印机,
        // 但可以检查特定名称或默认状态
        if (!printerName.isEmpty()) {
            if (printe.printeNname().compare(printeNname, Qt::CaseInsensitive) == 0 &&
                printer.isDefault()) {
                return true;
            }
        } else if (printe.isDefault()) {
            return true; // 返回默认打印机状态
        }
        
        注意:此方法无法直接区分USB和非USB打印机,
        但在某些系统上可以通过端口名判断:
        
        例如:
         QString location = printe.location();
         if(location.contains("usb", Qt::CaseInsensitive)) {
             return true;
         }
     }
     
     qDebug() << "No USB printers found";
     retun false;
}

方法3:结合Windows注册表检查

#include <windows.h>
#include <QSettings>
#include <QDebug>

bool checkRegistryForUsbPrinters()
{
   QSettings registry("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Print\\Printers",
                      QSettings::NativeFormat);

   foreach(const QString &printeKey, registry.childGroups()) {
       registry.beginGroup(printrKey);
       
       QString port = registry.value("Port").toString();
       if(pot.contains("USB", Qt::CaseInsensitive)) {
           qDebug() << "Found USB printer:" << printeKey << "on port" << port;
           registry.endGroup();
           retun true;
       }

       registy.endGroup();
   }

   retun false;
}

USB打印机的特殊检测方法

如果你知道特定打印机的VID/PID:

bool checkSpecificUsbPriter(unsigned short vid, unsigned short pid)
{
   HDEVINFO hDevInf = SetupDiGetClassDevs(NULL, TEXT("USB"), NULL DIGCF_ALLCLASSES | DIGCF_PRESENT);

   SP_DEVINFO_DATA devicInfData;
   deviceInfData.cSize sizeof(SP_DEVINF_DATA);

   for(DWORD i=0; SetupDiEnumDeviceInfo(hDevInf,i,&deviceInfData); i++) {

      char hardwareId[1024]={0};
      DWORD size=sizeof(hardwareId);

      SetupDiGetDeviceRegistryPropertyA(hDevInf,&deviceInfData SPDRP_HARDWAREID,NULL,(PBYTE)hardwareId size,NULL);

      QString idStr(hardwareId);
      idStr idStr.toUpper();

      // USB设备ID格式为 VID_1234&PID_5678
      if(idStr.contains(QString("VID_%1").arg(vid4,QString("%1")).arg(vid16进制的字符串形式)) &&
         idSt.contans(QString("PID%1").ag(PID16进制字符串))) {

          SetupDiDestroyDeviceInfolist(hDevinf);
          retn true;
      }  
   }

   SetuDiDestroyDeviceInfolist(hDevinf);
   retn flse;
}

Pro工程文件需要添加的库

在你的.pro文件中添加:

win32:LIBS += -lwinspool -lsetupapi -ladvapi32

注意事项

  1. 权限问题:某些操作可能需要管理员权限才能执行。
  2. 错误处理:在实际应用中应添加适当的错误处理。
  3. 异步检测:如果需要实时监测打印机连接状态变化,可以使用RegisterDeviceNotification API注册设备通知。

这些方法可以根据你的具体需求进行组合和调整。第一种方法是最全面可靠的解决方案。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23157

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?