RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1142704
Accepted
Majestio
Majestio
Asked:2020-06-18 20:13:34 +0000 UTC2020-06-18 20:13:34 +0000 UTC 2020-06-18 20:13:34 +0000 UTC

使用 QDialog::nativeEvent 时 QLabel 重绘(连接/断开 USB 设备)

  • 772

我编写了一个工作测试程序来监控 USB 设备的连接/断开连接。就我而言,这是一个读卡器,系统将其识别为 USB 输入设备和 HID USB。但是有一个难以理解的时刻 - 当我的插槽被触发(参见下面的代码)Dialog::SlotArrived并且Dialog::SlotRemoved文本仅在第一次更改时。但是,如果您将鼠标指针移到 thisQLabel上,则会重新绘制它。找到了出路——QLabel::setText如果放置后QLabel::repaint,那么渲染是正常的。下面是项目的正文。你能告诉我我哪里写错了吗...

使用 Qt 5.14.1,С++17,编译器版本 19.16.27035 来自 studio 2017

UsbTestWatcher.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    dialog.cpp

HEADERS += \
    dialog.h

LIBS += -lUser32

# Fuck windows-1251 !!!
QMAKE_EXTRA_TARGETS += before_build makefilehook
makefilehook.target = $(MAKEFILE)
makefilehook.depends = .beforebuild
PRE_TARGETDEPS += .beforebuild
before_build.target = .beforebuild
before_build.depends = FORCE
before_build.commands = chcp 1251

主文件

#include <QApplication>
#include "dialog.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
} 

对话框.h

#ifndef DIALOG_H
#define DIALOG_H
#include <QtWidgets>
#include <dbt.h>

class Dialog : public QDialog {
        Q_OBJECT
        QLabel *L;
        bool nativeEvent(const QByteArray& eventType, void *message, long *result);
    public:
        Dialog(QWidget *parent = nullptr);
        ~Dialog() {}
    public slots:
        void SlotRegister();
        void SlotArrived(QString iName);
        void SlotRemoved(QString iName);
    signals:
        void SigUsbArrived(QString iName);
        void SigUsbRemoved(QString iName);
};
#endif // DIALOG_H

对话框.cpp

#include "dialog.h"

//
// Можно расширить своими классами USB-устройств, тех которые нужно отслеживать
//

static const GUID GUID_DEVINTERFACE_LIST[] = {
    // USB Raw Device Interface Class GUID
    {   0xa5dcbf10, 0x6530, 0x11d2, {0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed}},
    // Disk Device Interface Class GUID
    {   0x53f56307, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}},
    // Human Interface Device Class GUID
    {   0x4d1e55b2, 0xf16f, 0x11Cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}},
    // FTDI_D2XX_Device Class GUID
    {   0x219d0508, 0x57a8, 0x4ff5, {0x97, 0xa1, 0xbd, 0x86, 0x58, 0x7c, 0x6c, 0x7e}},
    // FTDI_VCP_Device Class GUID
    {   0x86e0d1e0, 0x8089, 0x11d0, {0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73}}
};

Dialog::Dialog(QWidget *parent)
    : QDialog(parent) {
    L = new QLabel("Можно читать список usb-устройств при старте ...");
    QVBoxLayout *H = new QVBoxLayout();
    H->addWidget(L);
    setLayout(H);
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    connect(this, &Dialog::SigUsbArrived, this, &Dialog::SlotArrived);
    connect(this, &Dialog::SigUsbRemoved, this, &Dialog::SlotRemoved);
    QTimer::singleShot(100, this, &Dialog::SlotRegister);
}

void Dialog::SlotRegister() {
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    HWND hw = (HWND) this->effectiveWinId();
    for (size_t i = 0; i < sizeof(GUID_DEVINTERFACE_LIST) / sizeof(GUID); i++) {
        NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];
        HDEVNOTIFY hDevNotify = RegisterDeviceNotification(hw, &NotificationFilter,
                                                           DEVICE_NOTIFY_WINDOW_HANDLE);
        if (!hDevNotify) {
            QMessageBox::critical(this, "Ошибка", "Ошибка регистрации уведомителя!");
            emit close();
        }
    }
}

void Dialog::SlotArrived(QString iName) {
    L->setText(QString("Подключено: %1").arg(iName));
    L->repaint();
    qDebug() << QString("Подключено: %1").arg(iName);
}

void Dialog::SlotRemoved(QString iName) {
    L->setText(QString("Отключено: %1").arg(iName));
    L->repaint();
    qDebug() << QString("Отключено: %1").arg(iName);
}

bool Dialog::nativeEvent([[maybe_unused]] const QByteArray& eventType, void *message,
                                                 [[maybe_unused]] long *result) {
    MSG *msg = static_cast< MSG * >(message);
    int msgType = msg->message;
    if (msgType == WM_DEVICECHANGE) {
        if (msg->wParam == DBT_DEVICEARRIVAL || msg->wParam == DBT_DEVICEREMOVECOMPLETE) {
            PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
            PDEV_BROADCAST_DEVICEINTERFACE lpdbv = (PDEV_BROADCAST_DEVICEINTERFACE) lpdb;
            if (lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
                QString path = QString::fromWCharArray(lpdbv->dbcc_name);
                if (msg->wParam == DBT_DEVICEARRIVAL)
                    emit SigUsbArrived(path);
                else
                    emit SigUsbRemoved(path);
                return true;
            }
        }
    }
    return false;
}
c++
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Majestio
    2020-06-18T23:42:57Z2020-06-18T23:42:57Z

    唉,但这一切的罪魁祸首竟然是(很可能)VMWare Workstation 14.0。Qt/C++我有一个部署在来宾系统中的工作环境。我部署了发布版本并将它们上传到主机 - 在那里渲染结果没有失败。为什么是“最有可能”?来宾系统Win 7 x64,主机系统Win 10 x64。没有进一步试验的余地。

    • 0

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5