Russian Qt Forum

Qt => ActiveX => Тема начата: daorus от Апрель 02, 2011, 20:47



Название: Свойства на русском языке (для 1с)
Отправлено: daorus от Апрель 02, 2011, 20:47
Кто-нибудь уже нашел способ как можно доставать значения свойств на русском языке из 1с? На пхп у меня всё достается, а на qt все, что англоязычное - ок, а как требуется получить свойство русскоязычного реквизита - встрял

Код:
QString value = row->dynamicCall("ФИОплательщика").toString(); // исксепшн: такого кракосябры свойтсва нету
$value = $row->ФИОплательщика; // всё работает ок

// при этом запись загружена, падает именно свойство
bool ok = row->dynamicCall("Next()").toBool(); // == true

Я пробовал копаться в сорсах и мне показалось, что там toLatin() слишком часто используется, но действительно ли в нем проблема - хз - страшно править - а то вообще работать перестанет.

Может уже кто что придумал?


Название: Re: Свойства на русском языке (для 1с)
Отправлено: lit-uriy от Апрель 02, 2011, 21:12
а ты пробовал сделать программу с единственной кнопкой, на которой написано "Привет"?


Название: Re: Свойства на русском языке (для 1с)
Отправлено: Sahab от Апрель 02, 2011, 22:04
я бы использовал другую надпись на кнопке ;D


Название: Re: Свойства на русском языке (для 1с)
Отправлено: madRoger от Апрель 02, 2011, 22:51
Ну что, смотрю, никто не хочет отвечать. Видать, все устали отвечать на этот вопрос. Он достаточно прост.
lit-uriy не зря предложил автору вопроса создать кнопку с надписью на кириллице. Если создать такую кнопку, вместо надписи на ней будут те же кракосябры.
Дело в том, что класс QString оперирует двухбайтными символами в формате Unicode. Соответственно, необходимо преобразовать однобайтовые строки к типу QString. Для этого есть несколько методов. Либо использовать метод QString::fromLocal8Bit.(при этом используется системная кодировка). Либо воспользоваться кодеком QTextCodec.
Последний более предпочтителен так как его можно использовать для всего проекта сразу.

Попробуйте вместо  
Цитировать
row->dynamicCall("ФИОплательщика").toString();
написать row->dynamicCall(QString::fromLocal8Bit("ФИОплательщика"));

Либо воспользуйтесь кодеком, например:

 QTextCodec::setCodecForTr(       QTextCodec::codecForName("Windows-1251"));
 QTextCodec::setCodecForCStrings( QTextCodec::codecForName("Windows-1251"));

кодек лучше запихнуть в main.cpp.


Название: Re: Свойства на русском языке (для 1с)
Отправлено: daorus от Апрель 03, 2011, 09:29
на этот вопрос

Возможно я действительно что-то напутал с кодировками, поэтому привожу полный текст теста, может я действительно что-то проглядел.

Код:
#include <QTextCodec>
#include <QtGui/QApplication>
#include <ActiveQt/QAxObject>
#include <iostream>
#include "dumper.h"

/*
 * Содержимое dumper.h
 *
#include <QtCore/QObject>
class Dumper : public QObject
{
    Q_OBJECT

public slots:
    void print(int, QString, QString, QString);

};
 */

#define str QString
#define axo QAxObject

void Dumper::print(int code, str s1, str s2, str s3)
{
    std::cout << "1с ошибка: " << s2.toUtf8().constData() << std::endl;
}

void exposeErr(QObject* cry)
{
    Dumper ex;
    QObject::connect
    (
        cry
        , SIGNAL(exception(int, QString, QString, QString))
        , &ex
        , SLOT(print(int, QString, QString, QString))
    );
}

int main(int argc, char *argv[])
{
    // QCoreApplication не поддерживает com-инициализацию
    QApplication app(argc, argv);

    QTextCodec* utf8 = QTextCodec::codecForName("utf8");
    QTextCodec* cp1251 = QTextCodec::codecForName("cp1251");
    QTextCodec* cp866 = QTextCodec::codecForName("cp866");
    QTextCodec::setCodecForCStrings(utf8);

    axo v81("V81.COMConnector");

    exposeErr(&v81);
    axo* serv = v81.querySubObject("Connect(QString)", str("File=C:/Temp/1cГлав"));
    if (serv) std::cout << "Соединение есть" << "\n";

    exposeErr(serv);
    axo* qry = serv->querySubObject("NewObject(QString)", str("Запрос"));
    qry->dynamicCall("Text", str("ВЫБРАТЬ * ИЗ Справочник.Договоры"));
    axo* res = qry->querySubObject("Execute()");
    axo* row = res->querySubObject("Choose()");
    exposeErr(row);
    bool ok =  row->dynamicCall("Next()").toBool();
    std::cout << "выбран ли ряд: " << ok << std::endl; // результат: 1

    // вот в этом месте вылетает ошибка
    // причем ошибка не 1с, иначе она перехватилась
    // бы через дампер, а ошибка QAxBase
    str fio = row->dynamicCall("ФИОплательщика").toString();
   
    return 0;
}


Теперь запускаем полученное изделие:
Код:
> test.exe > txt.txt 2>&1

получаем вывод
(http://www.prog.org.ru/index.php?action=dlattach;topic=17499.0;attach=3217)

Тут же запускаем пхп аналог:
Код:
> php com.php > php-dump.txt 2>&1

и всё у нас отлично работает - данные извлекаются

Код:
<?
echo "Привет, начнем работу..."."\n";
$v8 = new COM("V81.COMConnector", NULL, CP_UTF8) or die("no-connection");
$serv = $v8->Connect("File=C:/Temp/1cГлав;");
$qry = $serv->NewObject("Запрос");
$qry->Text = "ВЫБРАТЬ * ИЗ Справочник.Договоры";
$res = $qry->Execute();
$row = $res->Choose();
$ok = $row->Next();
// var_dump($row); // нельзя - падает
echo "<br>".$row->ФИОплательщика."<br>"; // результат: Петрова
?>


=============================================

Параметры:
qt 4.7.2, mingw, windows xp sp3, 1c 8.1, php 5.2.5
кодировка всех исходных файлов, включая *.cpp, *.h, *.php - utf8


Название: Re: Свойства на русском языке (для 1с)
Отправлено: lit-uriy от Апрель 03, 2011, 10:01
>>кодировка всех исходных файлов, включая *.cpp, *.h, *.php - utf8
Самый простой способ такой:
Код
C++ (Qt)
str fio = row->dynamicCall(QObject::trUtf8("ФИОплательщика")).toString();

т.е. все строчки содержащие кириллицу обернуть в QObject::trUtf8().

Может показаться, что trUtf8() нужна только для перевода, однако здесь нам от неё нужна простота записи и преобразование из строкового литерала в кодировке UTF-8 в UTF-16 (используемой внутри QString)


Название: Re: Свойства на русском языке (для 1с)
Отправлено: daorus от Апрель 03, 2011, 10:39
Самый простой способ такой:
Код
C++ (Qt)
str fio = row->dynamicCall(QObject::trUtf8("ФИОплательщика")).toString();

т.е. все строчки содержащие кириллицу обернуть в QObject::trUtf8().

Странно, что вы советуете, не проверив прототип dynamicCall(). Вы уверены, что у вас типы совпадают?


Название: Re: Свойства на русском языке (для 1с)
Отправлено: lit-uriy от Апрель 03, 2011, 11:33
daorus ну приведи QString к Сишной строке через toLocal8bit, Суть-то не в этом. Суть в том, что на винде никто не ждёт символов в UTF-8, а исходник у тебя в UTF-8.
И нужно преобразовать из UTF-8 в CP-1251, самый простой путь - преобразовать UTF-8 в QString (UTF-16), а QString уже к чему угодно.


Название: Re: Свойства на русском языке (для 1с)
Отправлено: daorus от Апрель 03, 2011, 12:06
на винде никто не ждёт символов в UTF-8, а исходник у тебя в UTF-8

Доказательства этого тезиса есть? Или просто - фантазии на тему?
Потому что вот это тоже не работает.

Код:
const char* cp1251form = cp1251->fromUnicode(str("ФИОплательщика"));
str fio = row->dynamicCall(cp1251form).toString();
   


Название: Re: Свойства на русском языке (для 1с)
Отправлено: lit-uriy от Апрель 03, 2011, 20:32
причём здесь fromUnicode()?
ты сам сказал , что у тебя UTF-8, а не я это с фантазировал:
>>кодировка всех исходных файлов, включая *.cpp, *.h, *.php - utf8