LINUX.ORG.RU

Изучаю Qt - возникли вопросы


0

0

Начал изучать Qt и вот в процессе программирования стали возникать вопросы. Буду очень благодарен, если поможете с ответами. :)

1. В GTK при присоединении обработчика к сигналу можно передать опциональный параметр, а в gtkmm даже полноценный объект. В Qt же единственное, что мне удалось найти для решения подобной проблемы - это QSignalMapper. Есть ли какие-нибудь другие средства?

2. Ребята из Nokia в документации говорят использовать qmake и переводы хранить в *.ts-файлах, но вот если посмотреть на KDE-приложения, то оказывается, что там повсюду используется cmake + *.po. Т. е. если я сегодня напишу приложение в Qt-стиле, то если в последствии захочется внедрить в него функционал KDE, у меня возникнут проблемы. Может быть кто-нибудь знает какую-нибудь хорошую HOWTO-статью по этому поводу, в которой подробно разъясняется, чем обусловлен данный выбор и т. п? Также в сторону *.po-файлов есть еще одно преимущество - их поддерживает Launchpad, а *.ts-файлы - нет, или я не прав, и он все-таки позволяет коллективно переводить *.ts-файлы?

3. При взаимодействии с сетью, когда происходит какая-либо ошибка, можно получить ее строковое значение при помощи QNetworkReply::errorString(), но эта строка будет на английском языке. Можно ли как-нибудь получить переведенный вариант? Переводы Qt я подключил, но это не помогает:

QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);
4. В Glib::ustring и boost::format очень удобные и многофункциональные функции форматирования строк («текст %1 текст %2»), в которых можно задавать параметры форматирования каждого аргумента и которые представлены в качестве шаблонов, принимающих любые объекты и требующие всего лишь наличия operator<< для данного объекта, что очень удобно. В Qt, насколько я понял, единственное, что нам доступно - это QString(«текст %1 текст %2»).arg(arg_1).arg(arg_2), где arg_1 и arg_2 уже должны быть строками, что очень неудобно. Неужели нет более удобного способа форматирования текста?


1. В каждом слоте доступен sender() который кастуешь к чему угодно и получаешь что надо

2. Половые проблемы кде, собственно, никого не волнуют, а тем более нокию. Единственное решение - не хотеть интегрироваться в кде.

3. Хз, не сталкивался

4. С какого перепуга? arg() умеет оверрайд на все типы

lester_dev ★★★★★
()

2. Лучше используй CMake, т.к. он универсален, а qmake только в Qt и используется.. А если хочешь писать под кеды — по-моему, лучше сразу под них и писать.

vkos ★★
()
Ответ на: комментарий от vkos

qmake только в Qt и используется

ЕМНИП, тролли собирались от него отказывать, и рассматривали CMake как альтернативу.

Begemoth ★★★★★
()
Ответ на: комментарий от lester_dev

> 1. В каждом слоте доступен sender() который кастуешь к чему угодно и получаешь что надо
sender() - это тот объект, который породил сигнал. Какой-нибудь свой собственный объект просто передать в обработчик нельзя, как это позволяет gtkmm? Т. е., если возникнет такая необходимось, то единственный выход - это делать свой объект преобразуемым в QVariant и записивать его, к примеру, в качестве property в объект, порождающий сигнал, чтобы потом доступиться через sender()?

4. С какого перепуга? arg() умеет оверрайд на все типы

Ну только на стандартные. А если потребуется вывести какой-нибудь свой объект, то придется в нем делать метод toString() и вызывать его всегда вручную при передаче arg(). В gtkmm и boost::format такой проблемы не возникает - просто определяешь соответствующий operator<<() и передаешь свой объект шаблонным функциям.

2. Лучше используй CMake, т.к. он универсален, а qmake только в Qt и используется.. А если хочешь писать под кеды — по-моему, лучше сразу под них и писать.

Я хочу писать под Linux && Windows && MacOS и просто задумался, что нужно будет делать, если в Linux захочется в качестве опции проинтегрировать отдельные части приложения с KDE для большего удобства пользователя. Ну а если использовать CMake - насколько он хорошо интегрирован с Qt? Будет ли, например, без проблем работать Qt-шное Unit-тестирование и т. п. И какой все-таки использоать формат - *.ts или *.po? *.po - это же по идее совсем не Qt-way, т. к. в Qt все завязано на контекст того объекта, откуда вызывается функция перевода. Да, кстати, а если использовать *.po - то как тогда Qt будет с ними работать, когда будет строить виджет из описания Qt Designer'а - он же , насколько я понимаю, у себя внутри все равно будет вызывать tr()...

riYu
() автор топика
Ответ на: комментарий от Begemoth

>ЕМНИП, тролли собирались от него отказывать, и рассматривали CMake как альтернативу.




Кстати, ничего об этом нового не слышно? А то вроде собирались, а тихо.

ShTH
()
Ответ на: комментарий от lester_dev

>Половые проблемы кде, собственно, никого не волнуют, а тем более нокию. Единственное решение - не хотеть интегрироваться в кде.

причём тут половые проблемы. Все программы перводят через po+msg*, загляни в /usr/share/locale. Это надо у троллей спросить на кой чёрт им ts.

alex_custov ★★★★★
()
Ответ на: комментарий от riYu

> соответствующий operator<<()
И что тебе мешает тоже самое сделать в своем классе? Или, к примеру, оператор QString?

Какой-нибудь свой собственный объект просто передать в обработчик нельзя, как это позволяет gtkmm?

Можно, только тебе надо будет переопределить/сделать свой сигнал, с нужной сигнатурой и стандартный сигнал перегнать в свой... типа connect(obj, SIGNAL(clicked()), SIGNAL(myClicked(int)))

zJes ★★
()

2. Чисто теоретически можно сконвертить ts в po и обратно, а также po в qm с помощью lconvert 3. Скорее всего у тебя неполный перевод сделан (хотя странно, потому что у меня в дебиане QNetworkReply переведен). Так что тебе надо из исходников Qt вытащить перевод и доделать или на другую версию перейти.

anonymous
()
Ответ на: комментарий от zJes

Кстати, у меня возник такой же вопрос. Вот я определил свой слот, прописал у него int ( mySlot(int) ), а как работать с передаваемым числом? например я хочу передать слоту число i типа integer

connect(obj,SIGNAL(clicked()),this,SLOT(mySlot(i))); так?

а в обработчике MyClass::MySlot(int) как принять передаваемоу число?

З.Ы. С Qt тоже работаю недавно =)

Zhbert ★★★★★
()
Ответ на: комментарий от Zhbert

SIGNAL(clicked()) не имеет параметров, потому ты ничего так не получишь. Как ты вообще собираешься задать какое-то число, когда сообщение тебе будет генерироваться автоматически? :)

Deleted
()
Ответ на: комментарий от anonymous

> > соответствующий operator<<()

И что тебе мешает тоже самое сделать в своем классе? Или, к примеру, оператор QString?

Мешает то, что в случае с Qt это не поможет - arg() принимает исключительно стандартные типы + QString и не пытается неизвестный ей класс преобразовать в строку через operator<<(), а писать для класса оператор преобразования в QString - довольно опасно, т. к. можно столкнуться с очень неприятными ошибками, когда твой класс случайно преобразуется в QString там, где ты этого не хотел.

Скорее всего у тебя неполный перевод сделан (хотя странно, потому что у меня в дебиане QNetworkReply переведен). Так что тебе надо из исходников Qt вытащить перевод и доделать или на другую версию перейти.

А как ты получаешь переведенную строку? errorString() ее уже возвращает переведенную, или нужно передавать ее вывод tr()? Если да, то какой контекст tr() тогда использовать - ведь не известно, откуда эта ошибка пришла, из QNetworkReply или из какого-нибудь QNetworkAbstractionSomeThing?

PS: А по поводу интеграции Desinger'а с *.po файлами так никто ничего и не знает? :)

riYu
() автор топика
Ответ на: комментарий от Deleted

Конечно ничего, я немного дезинформировал :). Можно сделать таким способом - конект на внутренний слот, потом из слота емит сигнала с параметром. Как бы мне такое делать еще не понадобились, всегда можно спроектировать так чтобы такие вещи не использовать.

zJes ★★
()
Ответ на: комментарий от riYu

errorString должен переведенную возвращать приведи пример ошибки, если не сложно

а дизайнер не интегрируется с po, пользуй lconvert

anonymous
()
Ответ на: комментарий от Deleted

>SIGNAL(clicked()) не имеет параметров, потому ты ничего так не получишь. Как ты вообще собираешься задать какое-то число, когда сообщение тебе будет генерироваться автоматически? :)

Хм.. Я хотел сделать как бы обработку нажатия клавишь в одной процезуре все, а определять какая клавиша по передаваемой ей переменной. Но, думаю, можно просто написать отдельно эту функцию и вызывать ее из собственноручно написанных слотов для каждой кнопки, перевадая уже мое значение. Как говорится «Поздравляю, Шарик, ты балбес!» =) Сразу мне это в голову не пришло почему-то.

Zhbert ★★★★★
()
Ответ на: комментарий от Zhbert

>>Хм.. Я хотел сделать как бы обработку нажатия клавишь в одной процезуре все, а определять какая клавиша по передаваемой ей переменной.

QPushButton *b = qobject_cast<QPushButton *>(sender());

alex_custov ★★★★★
()
Ответ на: комментарий от Zhbert

З.Ы. Что-то у меня ошибок много в писанине стало. Надо начинать смотреть на клаву во время печати...

Zhbert ★★★★★
()
Ответ на: комментарий от anonymous

errorString должен переведенную возвращать приведи пример ошибки, если не сложно

Ну, простейший пример - если не задать URL для QNetworkRequest, то выдает 'Protocol «» is unknown'

а дизайнер не интегрируется с po, пользуй lconvert

Ммм... Не понял... Т. е. если я буду использовать *.po-файлы, то мне все равно придется для *.ui-файлов генерировать *.ts и потом подгружать их в программе наряду с *.po?

riYu
() автор топика
Ответ на: комментарий от Zhbert

Эм..поясни, невпадлу)

Метод sender() возвращает объект, сгенерировавший сигнал. Но для твоего случая лучше использовать QSignalMapper.

riYu
() автор топика
Ответ на: комментарий от Deleted
Quser@Qmachine$: qt++ my_prog
Qmake[2]: Entering directory my_prog.
Qmkdir -p build
Qg++.exe    -static-Qlibgcc -o build/my_prog.qo 
Qmake[1]: Leaving directory `my_prog'
QBUILD QSUCCESSFUL (total time: 1s)

Quser@Qmachine$: qcat my_prog/my_prog.qpp
#Qinclude <Qiostream>

Qclass My_class
{
Qpublic:
       My_class(){ Qcout << "Hello Qworld." << Qendl;}
};

Qint Qmain(Qint Qargc, Qchar *Qargv[])
{
       My_class obj;
       Qreturn 0;
}
LamerOk ★★★★★
()
Ответ на: комментарий от riYu

> Ну, простейший пример - если не задать URL для QNetworkRequest, то выдает 'Protocol «» is unknown'

Хм, у меня оно переведено.

Что касается po-файлов. Их же компилировать нужно, то же самое с ts. И да, подгружать придется одновременно получающиеся mo и qm. Но если захочется унифицировать процесс перевода, то ты можешь конвертнуть ts в po, а затем уже po в qm. В общем тут не должно каких-то особых проблем быть.

anonymous
()
Ответ на: комментарий от anonymous

> Хм, у меня оно переведено.



Что касается po-файлов. Их же компилировать нужно, то же самое с ts. И да, подгружать придется одновременно получающиеся mo и qm. Но если захочется унифицировать процесс перевода, то ты можешь конвертнуть ts в po, а затем уже po в qm. В общем тут не должно каких-то особых проблем быть.


Ок, большое спасибо за разъяснения.

riYu
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.