RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-522379

Ingvar's questions

Martin Hope
Ingvar
Asked: 2024-04-10 16:51:01 +0000 UTC

显示存储在 dll/so 库资源中的 QIcons

  • 5

Qt 5/6 项目包含几个实现某些接口的插件库。svg格式的图标用于设计。在项目中使用是这样的:

QIcon(":img/datepicker.svg")

在库代码中它们的使用方式如下:

QIcon(":plgcomponents/img/datepicker.svg")

其中,在第一种情况下,img 是项目资源图标(exe 文件)的前缀,在第二种情况下,plgcomponents/img 是 dll 资源文件中使用的前缀。在 Windows 上构建时,一切都显示正常,但在 Linux 上构建时,图标不显示。

视窗

视窗

Linux

Linux

似乎唯一可见的图标是那些仅位于应用程序本身的资源文件中的图标。

问题:除了将图标转移到应用程序资源之外,还有其他解决方案吗?

c++
  • 1 个回答
  • 27 Views
Martin Hope
Ingvar
Asked: 2024-01-18 21:04:38 +0000 UTC

使用 Qt 5.x (C++) 生成 ODT/ODS 格式的报告

  • 5

小澄清: Qt 5.15.12

任务:需要编写一个函数,将一些数据上传到 Libre 和其他 Office 可读的 ODT 文档中。该算法应该适用于 Windows 和 Linux。最重要的是,强烈建议不要与计算机上是否存在 LibreOffice 挂钩。也就是说,程序不应该使用与第三方软件的链接(当然如果可能的话)。

该文档包含表的名称以及 3 列 N 行的表本身。可以有多个这样的表。但在一般情况下,报告很简单,没有添加图片或其他花哨的东西。

编写算法本身不是问题。得到的结果如代码所示:

QString strNoInfo ="-";
//-- создаём новый документ, который будет записан в файл
QTextDocument *doc = new QTextDocument();

//-- предварительная очистка документа, не факт, что нужно, но на всякий случай
doc->clear();

QTextCursor cursor(doc);
//-- подготовка форматов
//-- Заголовок
QTextCharFormat fmt_title;
fmt_title.setFont(QFont("Times New Roman", 12, QFont::Normal));
//-- заголовок столбцов таблицы
QTextCharFormat fmt_table_caption;
fmt_title.setFont(QFont("Times New Roman", 10, QFont::Normal));
//-- основной текст таблицы
QTextCharFormat fmt_table_text;
fmt_title.setFont(QFont("Times New Roman", 10, QFont::Normal));

//-- счётчик строк таблицы для расставления номеров п/п
//-- обнуляется для каждой новой таблицы
int cnt = 0;
for (int i = 0; i < data.count(); i++) {
    int table_num = i + 1;
    //-- указываем
    QString corrected_name = data[i]->name;
    QString title =
        QString("Таблица %1 - .... %2\n\n")
            .arg(QString::number(table_num), corrected_name);
    cursor.insertText(title, fmt_title);

    //-- 3 столбца с 20 строками (первая строка - заголовок таблицы)
    //-- указатель на формируемую таблицу
    QTextTable *tbl = cursor.insertTable(20, 3);
    cnt = 0;
    //-- формируем заголовки таблицы
    tbl->cellAt(cnt, 0).firstCursorPosition().insertText("№ п/п", fmt_table_caption);
    tbl->cellAt(cnt, 1).firstCursorPosition().insertText("Наименование",
                                                         fmt_table_caption);
    tbl->cellAt(cnt++, 2).firstCursorPosition().insertText("Значение поля", fmt_table_caption);

    tbl->cellAt(cnt, 0).firstCursorPosition().insertText(QString::number(cnt), fmt_table_text);
    tbl->cellAt(cnt, 1).firstCursorPosition().insertText("Поле 1", fmt_table_text);
    tbl->cellAt(cnt++, 2).firstCursorPosition().insertText(
        data[i]->vul_name.isEmpty() ? strNoInfo : data[i]->name, fmt_table_text);


    tbl->cellAt(cnt, 0).firstCursorPosition().insertText(QString::number(cnt), fmt_table_text);
    tbl->cellAt(cnt, 1).firstCursorPosition().insertText("Поле 2",
                                                         fmt_table_text);
    tbl->cellAt(cnt++, 2).firstCursorPosition().insertText(data[i]->vul_idval.isEmpty() ? strNoInfo : data[i]->value, fmt_table_text);
    ... и так далее ....

    cursor.movePosition(QTextCursor::End);
    cursor.insertText("\n\n", fmt_title);

}

问题 1:尝试使用多个 QTextCharFormat 变量(在代码开头指定)进行格式化不会产生任何结果。表格标题变为指定字体,但大小没有任何变化。表本身对指定的格式没有任何反应。看来 .insertText 函数并不关心描述格式的第二个参数。

在谷歌搜索之后,我没有找到一个易于理解的文档形成示例。阅读文档后,我发现了cursor.insertBlock(),它可能相当于Word中的一个段落,但是插入一个块并不会返回任何可以引用的东西。

问题 2:需要帮助生成 ODS 文件。除了QOds2(但是,它没有构建)之外,我没有找到任何库。所有技巧都归结为使用 LibreOffice SDK 和阅读 ODS 格式的描述。我可以读到,SDK是一个极端的例子,但是真的有更简单的解决方案吗?

我请求充分的建议(和/或代码更正)和评论。

UPD:生成的文档是用ODF编写的:

        QTextDocumentWriter *dw = new QTextDocumentWriter(fileName);
    dw->setFormat("odf");
    dw->write(doc);
    QDesktopServices::openUrl(QUrl::fromLocalFile(fileName));
c++
  • 1 个回答
  • 56 Views
Martin Hope
Ingvar
Asked: 2023-11-28 19:14:46 +0000 UTC

构建CMAKE项目时LINK找不到库

  • 6

编写多平台汇编的cmake文件时出现问题。详细信息:为了方便工作,我将项目分成几个库。我将数据库访问库移至单独的 dll 中。我会立即进行预订 - 如果所有模块都在主程序的主体中,那么它们都可以工作,也就是说,那里没有错误(目前:))

为了构建该项目,我创建了一个新的 cmake 项目,该项目作为子项目包含在主项目中:

cmake_minimum_required(VERSION 3.5)

project(plgconnector LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if (WIN32)
    message("[PLG CONNECTOR] Build Windows revision!")
    find_package(QT NAMES Qt5 COMPONENTS Widgets Core svg REQUIRED)
    find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core svg Widgets REQUIRED)
    find_package(PostgreSQL REQUIRED)
endif(WIN32)

if (UNIX AND NOT APPLE)
    message("[PLG CONNECTOR] Build Linux revision!")
    find_package(QT NAMES Qt5 COMPONENTS Core Widgets REQUIRED)
    find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED)
    find_package(PostgreSQL REQUIRED)
endif()

message("[PLG CONNECTOR] PostgreSQL VER: " ${PostgreSQL_VERSION_STRING})
message("[PLG CONNECTOR] Include files PostgreSQL: " ${PostgreSQL_INCLUDE_DIRS})
message("[PLG CONNECTOR] Lib files PostgreSQL: " ${PostgreSQL_LIBRARY_DIRS})

add_library(plgconnector SHARED
  plgconnector_global.h
  tconnector.cpp
  tnotifyer.cpp
  tquery.cpp
  treader.cpp
  tconnector.h
  pgerror.ui
  pgerror.h
  pgerror.cpp
  sqlhighlighter.h
  sqlhighlighter.cpp
  sqlloghlighter.h
  sqlloghlighter.cpp
)

include_directories(AFTER ${PostgreSQL_INCLUDE_DIRS})
link_directories(AFTER ${PostgreSQL_LIBRARY_DIRS} ${PLG_LIB})

if (WIN32)
    target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets
        "${PostgreSQL_LIBRARY_DIRS}/libpq.lib"
    )
endif(WIN32)

if (UNIX AND NOT APPLE)
    target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets pq)
endif()

target_compile_definitions(plgconnector PRIVATE PLGCONNECTOR_LIBRARY)

set_target_properties(plgconnector PROPERTIES
    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${PlatformDir}"
)

上面的项目文本可以正常工作,但我有一个问题。在我之前写的主项目中

if (WIN32)
    target_link_libraries(plgconnector Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets libpq
    )
endif(WIN32)

并且该项目组装组装都很正常,一切都很好。但是如果我只是在这里写libpq,那么在链接阶段我会收到一个错误,提示找不到该文件,但是如果我直接指定路径,那么一切都很好。此外,这个门框仅适用于 WIN32;在 Linux 中一切正常。

我不明白我做错了什么。毕竟有一段添加代码:

link_directories(AFTER ${PostgreSQL_LIBRARY_DIRS} ${PLG_LIB})

有人有什么想法吗?

UPD: MS VC 2022 用于 Windows 中的汇编。

c++
  • 1 个回答
  • 30 Views
Martin Hope
Ingvar
Asked: 2023-07-27 19:12:23 +0000 UTC

使用 PostgreSQL API 时 Qt 界面冻结

  • 5

我需要帮助诊断问题:

有一个项目 Qt 5.14.2,它是在多平台变体中开发的。适用于 PostgreSQL 数据库(从 9.x 到 15.x)。使用MSVC 2022 x64编译器在Win 10 x64中进行直接开发,并在Linux x64上进行测试。该项目不使用内置的 Qt pgsql 插件(有原因 - 但它们并不那么重要)。相反,编写了一组自己的接口类,通过 libpq 与 Postgre 交互,这允许您通过 API 对数据库进行完全控制。

有一项任务:在后台加载一个视图的结果。查询中的记录数量达到约 5 万条,并且一直在增长,尽管速度不是很快。实现了一个附加线程 QThread,它与程序并行加载必要的内容。

问题:发生 2 次冻结:

  • 第一,当线程中请求数据时,这是可以理解的,本质上不会影响任何事情;
  • 第二个 - 在下载过程结束时,现在它将程序界面冻结。

问题在于第二次冻结,或者更确切地说,它冻结了整个程序的界面,尽管纯粹从技术上来说这是可以理解的。

那么详细信息:

  1. 正如已经说过的,有自己的与 PostgreSQL 交互的对象,它们可以根据我的需要工作。如果代码很重要,我稍后会给出。
  2. 使用一个对象创建 QThread 来提供负载:
     void Model::LoadData()
        {
            //-- запускаем поток, загрузки данных
            load_thread = new QThread(); //-- переменная определена в классе
            load_thread->setObjectName("BW_load");
            mtLoader = new ubiVulLoader(&DataList);
            mtLoader->moveToThread(load_thread);
            connect(mtLoader, SIGNAL(setProgressMax(int)), this, SLOT(setProgressMax(int)));
            connect(mtLoader, SIGNAL(setProgress(int)), this, SLOT(setProgress(int)), Qt::DirectConnection);
            connect(mtLoader, SIGNAL(endProcess()), this, SLOT(endProcess()));
            connect(load_thread, SIGNAL(started()), mtLoader, SLOT(doLoad()));
            load_thread->start();
        }

最后(在发出 endProcess 之后),处理以下代码:

void Model::endProcess()
{
    emit sendProcessEnd();
    disconnect(mtLoader, SIGNAL(setProgressMax(int)), this, SLOT(setProgressMax(int)));
    disconnect(mtLoader, SIGNAL(setProgress(int)), this, SLOT(setProgress(int)));
    disconnect(mtLoader, SIGNAL(endProcess()), this, SLOT(endProcess()));
    load_thread->quit();
    load_thread->wait(); //-- или deleteLater() - без разницы
    delete mtLoader;
    delete load_thread;
}

doLoad() 函数本身(缩写)如下所示:

void mtLoader::doLoad()
{
    auto con = new TConnector();
    if (con->Open())
    {
        if (con->transactionStart())
        {
            //-- ВСЕ ДЕЙСТВИЯ ВЫПОЛНЯЮТСЯ В РАМКАХ ОДНОЙ (!!!) ТРАНЗАКЦИИ
            /*
            Использование функций доступа по номеру поля а не по его имени существенно ускоряет
            обработку.  */

            QString q_load =
                QString("select " ... тут много полей по порядку
                        " from table ..."); 

            TQuery *qc = con->CreateNewQuery("select count(*) from table");
            long cnt = 0;
            if (qc->Execute())
            {
                cnt = qc->FieldByNum(0).toLongLong();
            }
            delete qc;
            if (cnt > 0)
            {
                emit setProgressMax(cnt); //-- оповещение о максимуме
                recs->resize(cnt); 
                //-- чтобы не перегружать событиями основной интерфейс искусственно снизим частоту оповещения
                //-- см. в конец цикла
                auto step = cnt / 100;
                auto st = 0;
                int progress = 0;

                TQuery *q = con->CreateNewQuery(q_load);
                if (q->Execute())
                {
                    int cnt = q->getRowCount();
                    TData *rec = nullptr;
                    for (int i = 0; i < cnt; i++)
                    {
                        recs->data()[i] = new TData();
                        rec = recs->at(i);
                        //-- служебные поля таблицы
                        rec->id = q->FieldByNum(0).toLongLong(); 
                        rec->code = q->FieldByNum(2).toString();
                        rec->name = q->FieldByNum(1).toString();
                        
                        ... ну и так далее заполняем объект

                        //--
                        q->Next();

                        //-- чтобы не перегружать событиями основной интерфейс искусственно снизим частоту оповещения
                        //-- оповещение о прогрессе будем отсылать 1 раз за 1 процент выполнения, а не на каждую запись
                        st += 1;
                        progress+=1;
                        if (st > step)
                        {
                            st = 0;
                            emit setProgress(progress);  //-- оповещение о прогрессе выполнения
                        }
                    }
                    emit setProgress(progress);  //-- оповещение о прогрессе выполнения
                }
                else
                {
                    //-- в случае ошибки ...
                    con->transactionRollback();
                    con->Close();
                    delete q;
                    delete con;
                    return;
                }
                delete q; //-- <<<< FREEZE
            }
        }
        con->transactionRollback();
        con->Close();
    }
    delete con;
    emit endProcess(); //-- оповещение об окончании процесса
}

第二次冻结发生在对象 q 被删除时,在此期间执行以下代码:

...
    if (_res!=nullptr)
    {
        PQclear(_res); //-- <<<< FREEZE
        _res=nullptr;
    }
    ...

冰点标记为“FREEZE”。在最后的代码中,在终止查询之前需要调用函数来修复内存泄漏 - 这是 PostgreSQL API 的要求。

从理智上来说,我明白清除一个我大小的内存块原则上不是一件很快的事情,但是:一切都是在单独的线程中完成的,整个程序的界面被冻结。

第一个想法:制作(并完成)一个 DataReader 类型的对象,逐行读取,但它的工作速度要慢很多,因为从服务器接收到的每个记录都会调用这样的清理函数(当使用行模式时)。

第二个想法:TConnector / TQuery 对象是简单的类,而不是 QObject 的后代。还没检查过。

无论如何,问题出现了:当在单独的线程中使用服务器时,调用其 API 函数会导致整个程序的界面冻结。为什么?

UPD 1:C# 具有可直接与 PostgreSQL 配合使用的 NpgSQL。他有一个DataReader,使用它在连接到同一数据库的另一个项目中就不存在这样的困难。这里无法重复。

请分享您的想法。

c++
  • 1 个回答
  • 45 Views

Sidebar

Stats

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

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 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