您的位置:首页 > 文旅 > 旅游 > 上海公安信息网_织梦安装教程_数字化营销_市场推广的方法和规划

上海公安信息网_织梦安装教程_数字化营销_市场推广的方法和规划

2025/5/7 16:18:37 来源:https://blog.csdn.net/weixin_42148156/article/details/146421200  浏览:    关键词:上海公安信息网_织梦安装教程_数字化营销_市场推广的方法和规划
上海公安信息网_织梦安装教程_数字化营销_市场推广的方法和规划

开发环境

            操作系统: openkylin2qt版本  : 5.15.10

排查过程

        首先看下问题的现象,

问题现象

        

      复现问题的demo很简单,只能是从跟踪qt代码方面入手

            void MainWindow::on_pushButton_clicked(){QPrinter printer;QPrintDialog dialog(&printer,this);dialog.exec();}

        现在需要找一个代码的起点去跟踪,想了半天没有思绪,于是设置环境变量export QT_DEBUG_PLUGINS=1看看有没有提示,结果发现程序会在这一行阻塞一段时间

     load library  "xxx/plugins/printsupport/libcupsprintersupport.so"

        怀疑可能与加载libcupsprintersupport.so库有关,可以从QLibrary加载插件库的代码开始查,经过gdb+打日志双重定位下,找到了耗时的代码范围

            //这个函数在运行过程中被调用了多次QPrinterInfo QPrinterPrivate::findValidPrinter(const QPrinterInfo &printer){// Try find a valid printer to use, either the one given, the default or the first availableQPrinterInfo printerToUse = printer;if (printerToUse.isNull()) {printerToUse = QPrinterInfo::defaultPrinter(); //调用耗时1秒if (printerToUse.isNull()) {QStringList availablePrinterNames = QPrinterInfo::availablePrinterNames(); //调用耗时1秒if (!availablePrinterNames.isEmpty())printerToUse = QPrinterInfo::printerInfo(availablePrinterNames.at(0));}}return printerToUse;}//这个构造函数被调用了一次QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *prn): parent(p), propertiesDialog(nullptr), printer(prn),#if QT_CONFIG(cups)m_duplexPpdOption(nullptr),#endifoptionsPane(nullptr), filePrintersAdded(false){q = nullptr;if (parent)q = qobject_cast (parent->parent());widget.setupUi(parent);int currentPrinterIndex = 0;QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();if (ps) {const QStringList printers = ps->availablePrintDeviceIds(); //调用耗时1秒const QString defaultPrinter = ps->defaultPrintDeviceId();  //调用耗时1秒widget.printers->addItems(printers);const QString selectedPrinter = prn && !prn->printerName().isEmpty() ? prn->printerName() : defaultPrinter;const int idx = printers.indexOf(selectedPrinter);if (idx >= 0)currentPrinterIndex = idx;}widget.properties->setEnabled(true);#if QT_CONFIG(filesystemmodel) && QT_CONFIG(completer)QFileSystemModel *fsm = new QFileSystemModel(widget.filename);fsm->setRootPath(QDir::homePath());widget.filename->setCompleter(new QCompleter(fsm, widget.filename));#endif_q_printerChanged(currentPrinterIndex);QObject::connect(widget.printers, SIGNAL(currentIndexChanged(int)),parent, SLOT(_q_printerChanged(int)));QObject::connect(widget.fileBrowser, SIGNAL(clicked()), parent, SLOT(_q_btnBrowseClicked()));QObject::connect(widget.properties, SIGNAL(clicked()), parent, SLOT(_q_btnPropertiesClicked()));// disable features that QPrinter does not yet support.widget.preview->setVisible(false);}//上面调用耗时的函数就是下面这两个QStringList QCupsPrinterSupport::availablePrintDeviceIds() const{QStringList list;cups_dest_t *dests;int count = cupsGetDests(&dests); //调用耗时1秒list.reserve(count);for (int i = 0; i < count; ++i) {QString printerId = QString::fromLocal8Bit(dests[i].name);if (dests[i].instance)printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);list.append(printerId);}cupsFreeDests(count, dests);return list;}QString QCupsPrinterSupport::staticDefaultPrintDeviceId(){QString printerId;cups_dest_t *dests;int count = cupsGetDests(&dests); //调用耗时1秒for (int i = 0; i < count; ++i) {if (dests[i].is_default) {printerId = QString::fromLocal8Bit(dests[i].name);if (dests[i].instance) {printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);break;}}}cupsFreeDests(count, dests);return printerId;}

               cupsGetDests是cups库的api

 (1) cups 是一个开放源代码的打印系统,为Unix类操作系统(如Linux)提供了标准的打印架构。(2) libcupsprintersupport.so库为qt开发者提供更便捷的api, libcupsprintersupport.so库内部调用的还是cups库api

                

               我单独写了一个调用cups api的demo,进一步验证是cupsGetDests耗时

            #include < cups/cups.h >#include < iostream >#include < ctime >#include < sys/time.h >//编译命令 g++ test.cpp -lcups/*开始 cupsGetDestsTimestamp (milliseconds): 1742524701156Timestamp (milliseconds): 1742524702187结束 cupsGetDests开始 cupsFreeDestsTimestamp (milliseconds): 1742524702187Timestamp (milliseconds): 1742524702187结束 cupsFreeDests*/void getime(){struct timeval tv;gettimeofday(&tv, nullptr);long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;std::cout << "Timestamp (milliseconds): " << timestamp << std::endl;}int main() {// 获取打印机列表cups_dest_t* dests = nullptr;std::cout << "开始 cupsGetDests" << std::endl;getime();int num_dests = cupsGetDests(&dests);  //此处耗时大约1秒getime();std::cout << "结束 cupsGetDests" << std::endl;/*if (num_dests == 0) {std::cerr << "No printers found!" << std::endl;return 1;}*/// 遍历打印机列表for (int i = 0; i < num_dests; i++) {cups_dest_t& dest = dests[i];// 打印打印机名称std::cout << "Printer Name: " << dest.name << std::endl;// 打印打印机是否默认if (dest.is_default) {std::cout << "  (Default Printer)" << std::endl;}// 打印打印机选项for (int j = 0; j < dest.num_options; j++) {std::cout << "  Option: " << dest.options[j].name<< " = " << dest.options[j].value << std::endl;}std::cout << std::endl;}// 释放打印机列表std::cout << "开始 cupsFreeDests" << std::endl;getime();cupsFreeDests(num_dests, dests);getime();std::cout << "结束 cupsFreeDests" << std::endl;return 0;}

排查结论

        qt程序运行过程中使用cups库的api,调用api耗时,导致qt组件弹出慢

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com