您当前的位置: 首页 > 

《QDebug 2022年8月》

发布时间:2022-08-31 22:43:38 ,浏览量:9

一、Qt Widgets 问题交流 1.QWidget鼠标事件穿透

对于一些透明或者半透明的QWidget,可能需要点击其下方的按钮或其他组件,但是QWidget本身是会接收这些鼠标事件的,需要一些额外的处理。下面是百度到的一些方法:

方式A.设置setAttribute(Qt::WA_TransparentForMouseEvents, true),设置之后该QWidget对象树就不再处理鼠标事件。最大的缺点就是不仅该QWidget不响应鼠标事件,它上面的其他组件也没法响应鼠标事件了。

方式B.setMask把底部要点击的地方抠出来,缺点是抠出来的地方就成了全透明,不适合半透明的需求:

QRegion reg(ui->widget->rect());
    //bottom为被widget挡住的按钮
    auto btn_area=ui->btnBottom->geometry();
    btn_area.moveTo(btn_area.topLeft()-ui->widget->geometry().topLeft());
    reg-=QRegion(btn_area);
    ui->widget->setMask(reg);

方法C. QWdidget鼠标事件处理先判断坐标点下方是否有其他组件,有则传递下去:

void mouseMoveEvent(QMouseEvent *event){
    transMouseEvents(event);
}

void mousePressEvent(QMouseEvent *event){
    transMouseEvents(event);
}

void mouseReleaseEvent(QMouseEvent *event){
    transMouseEvents(event);
}

void mouseDoubleClickEvent(QMouseEvent *event){
    transMouseEvents(event);
}

void transMouseEvents(QMouseEvent *event){
    if (this->parentWidget()) {    
        this->setAttribute(Qt::WA_TransparentForMouseEvents, true);
        QPoint pt = this->mapTo(this->parentWidget(), event->pos());
        QWidget *wid = this->parentWidget()->childAt(pt);
        if (wid) {
            pt = wid->mapFrom(this->parentWidget(), pt);
            QMouseEvent *mEvent = new QMouseEvent(event->type(), pt, event->button(), event->buttons(), event->modifiers());
            QApplication::postEvent(wid, mEvent);
        }
        this->setAttribute(Qt::WA_TransparentForMouseEvents, false);
    }
}

参考:QT 鼠标穿透 - 知乎 

二、Qt Quick 问题交流 1.打包命令问题

百度搜(QML打包),找到的结果一般都是这样的:

windeployqt 程序.exe --qmldir C:\Qt\Qt5.15.2\5.15.2\msvc2019_64\qml

这些博文上,--qmldir的参数一般都是指向Qt安装目录,但是通过查看文档可知,qmldir应该指向项目源码的qml目录,以查找导入了哪些模块,qmlimport才是用来指向安装路径或者其他依赖模块路径的。

文档:https://doc.qt.io/qt-5/windows-deployment.html 

三、其他 1.QAXObject在WPS环境下读取Excel的UsedRange.Value为空

一开始测试MS Office时如下的代码可以正常的读取到UsedRange的表格内容:

QAxObject *used_range = work_sheet->querySubObject("UsedRange");
auto range_data = used_range->property("Value").toList();

但是在测试WPS时,读取到的值是空的,修改为dynamicCall后就能正常读取了:

QAxObject *used_range = work_sheet->querySubObject("UsedRange");
auto range_data = used_range->dynamicCall("Value()").toList();

完整的测试代码如下:

void parseExcel()
{
    const QString filepath = QFileDialog::getOpenFileName(this);
    if(filepath.isEmpty()){
        qDebug()<<"filepath is empty";
        return;
    }

    QSharedPointerexcel{new QAxObject};
    //分别尝试WPS和MS Office的excel组件
    if(!excel->setControl("KET.Application" )){
        qDebug() << "open wps excel failed";
        if(!excel->setControl("Excel.Application")){
            qDebug() << "open office excel failed";
            return;
        }
    }

    qDebug()<<"excel open";
    auto scope = qScopeGuard([=]{
        qDebug()<<"excel quit";
        //退出时关闭,不然excel进程没退出
        excel->dynamicCall("Quit()");
    });
    Q_UNUSED(scope)

    excel->setProperty("Visible", false);
    excel->setProperty("EnableEvents", false);
    excel->setProperty("DisplayAlerts", false);
    QAxObject *work_books = excel->querySubObject("WorkBooks");
    if(!work_books){
        qDebug()<<"query WorkBooks error";
        return;
    }
    work_books->dynamicCall("Open(const QString&)", filepath);
    QAxObject *active_book = excel->querySubObject("ActiveWorkBook");
    if(!active_book){
        qDebug()<<"query ActiveWorkBook error";
        return;
    }else{
        qDebug()<<"book open";
        auto book_scope = qScopeGuard([=]{
            qDebug()<<"book close";
            //bool是否保存修改
            active_book->dynamicCall("Close(Boolean)", false);
        });
        Q_UNUSED(book_scope)

        QAxObject *work_sheet = active_book->querySubObject("WorkSheets(int)", 1);
        if(!work_sheet){
            qDebug()<<"query WorkSheets error";
            return;
        }
        QAxObject *used_range = work_sheet->querySubObject("UsedRange");
        if(!used_range){
            qDebug()<<"query UsedRange error";
            return;
        }
        //全部读取,范围是上下左右最边上的数据所围城的矩形区域
        auto range_data = used_range->dynamicCall("Value()").toList();
        qDebug()<<"range data:"<            
关注
打赏
1688896170
查看更多评论

暂无认证

  • 9浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0424s