Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno C++ - Pretypovanie v Qt

Problém je ten, že ak napíšem niečo takéto, síce to prejde, ale nemám zobrazené znaky s diakritikou:

str = QString::fromUtf8("Deň");

Toto mi odmieta skompilovať:
QString str;

str = QString::fromUtf8((const char *)str.sprintf("%d. deň v roku", den));

Nefunguje to ani takto:

str = QString::fromUtf8(str.sprintf("%d. deň v roku", den));

Túto premennú potom vkladám do QLabel:

ui->lblPopis->setText(str);

Predpokladám, že je problém iba v pretypovaní, ale netuším čo s tým. Mohli by ste mi poradiť ako to správne pretypovať? Prípadne, ak by ste mi mohli poradiť, ako to vložiť celé do jedného riadku ui->lblPopis->setText(...).

Předmět Autor Datum
1.problem = pravdepodobne nepises zdrojak v UTF8. Pouzi editor ktory vie UTF8 a aj to v nom nastav.…
MM.. 11.10.2011 19:28
MM..
Chybová hláška súvisí s názvom diskusie (pretypovanie). Potrebujem pretypovať QString na const char…
msx. 11.10.2011 20:08
msx.
nie, nepotrebujes nic pretypovat. Ja by som chcel pretypovat hov** na zlate tehly. Ale tiez to nejde…
MM.. 11.10.2011 20:11
MM..
str = QString::fromUtf8((const char *)str.sprintf("%d. deň v roku", i)); invalid cast from type 'QS…
msx. 11.10.2011 20:16
msx.
Ale ved ti cely cas pisem ze to pretypvat nejde (invalid casting), pretypovat sa neda cokolvek na co…
MM.. 11.10.2011 20:19
MM..
Ak to vyhodím nepôjde to.
msx. 11.10.2011 20:20
msx.
Co nepojde?
MM.. 11.10.2011 20:21
MM..
ui->lblPopis->setText(str.sprintf("%d. deň v roku", den)); Co na tom nefunguje? nefunguje tam ten m…
MM.. 11.10.2011 20:24
MM..
TAkže povedz rovno, že mám zabudnúť na formátovanie. Chápal som to úplne inak, než si písal.
msx. 11.10.2011 20:32
msx.
Nemusis "zabudnut na formatovanie", existuje vela sposobov ako to robit spravne, napr. pomocou .arg,…
MM.. 11.10.2011 20:42
MM..
Ked chces obist obmedzenia sprintf, mozes si napr. urobit pomocou sprintf len to "%d" a zbytok prida…
MM.. 11.10.2011 20:36
MM..
Neprogramujem Nokiu, to je klasické programovanie desktopovej aplikácie. Akurát, že to celé vlastní…
msx. 11.10.2011 22:44
msx.
BTW. nejak celkom nechapem co to tam robis s tym QString::fromUtf8(str.sprintf("%d. deň v roku", den…
MM.. 11.10.2011 19:51
MM..
Ten prvý kód úplne hore čo je mi funguje (pomýlil som sa, keď som písal otázku), ale ak miesto reťaz…
msx. 11.10.2011 20:03
msx.
Aby som doplnil, tá funkcia na prevod z UTF-8 konvertuje do UTF-16, ak som to celé fungovanie pochop…
msx. 11.10.2011 20:04
msx.
pochopil si to asi blbo, sprintf je pouzitelny na premennu triedy QString a teda tu premennu zrejme…
MM.. 11.10.2011 20:09
MM..
fromUtf8 tam treba, s tým to funguje. Potrebujem pretypovať výsledok funkcie sprintf na const char *…
msx. 11.10.2011 20:19
msx.
Kódovanie zdrojáku je CP 1250. Ale do akého kódu to prevádza kompilátor netuším, pravdepodobne UTF-8…
msx. 11.10.2011 20:07
msx.
kompilator to neprevadza do nicoho. Ked chces string previest kompilerom tak to musis napisat do zdr…
MM.. 11.10.2011 20:11
MM..
Ahoj, jak správně píše MM.., je potřeba použít editor podporující UTF-8 (a soubor uložit jako UTF-8!…
hvězd 11.10.2011 20:34
hvězd
Správná odpověď by teda měla být tato: Formátování se v Qt dělá takto: str = QString("%1. deň v ro…
hvězd 11.10.2011 20:47
hvězd
A keby chcem 2 argumenty, čo potom? Dokumentácia sa tvári tak, ako keby to nešlo. Konkrétne som skúš…
msx. 11.10.2011 22:54
msx.
Podle mě by mělo jít: QString("%1. deň v roku %2").arg(den).arg(rok) ale nezkoušel jsem to. Funkc…
hvězd 12.10.2011 19:39
hvězd
Toto je zaujímavé aj pre mňa do budúcnosti.
msx. 11.10.2011 22:55
msx.
Takže toto pomohlo, samozrejme musel som Qt prinútiť, aby zobralo aj UTF-8. To som dosiahol tak, že…
msx. 11.10.2011 22:47
msx.
A vies vobec co si to urobil? Konvertujes Latin1->Qstring(UTF16)->toASCII->fromUTF8 do QString(UTF16…
MM.. 12.10.2011 19:47
MM..
Áno, neskôr som zistil, že ani to nie je ideálne riešenie a prešiel som na arg(). Musím uznať, s tým… poslední
msx. 20.10.2011 20:21
msx.

1.problem = pravdepodobne nepises zdrojak v UTF8. Pouzi editor ktory vie UTF8 a aj to v nom nastav.
Ostatne problemy neviem ptz sa mi nechce hladat prototypy tych fcii googlom. A navyse si sem nedal text chybovej hlasky compilera, v ktorej je v 99% pripadov uplne presne napisane ze co s tym mas robit aby to skompiloval.

str = QString::fromUtf8((const char *)str.sprintf("%d. deň v roku", i));

invalid cast from type 'QString' to type 'const char*'

str = QString::fromUtf8(str.sprintf("%d. deň v roku", i));

no matching function for call to 'QString::fromUtf8(QString&)'

Prototyp, ktorý chcem volať je tento:

QString QString::fromUtf8 ( const char * str, int size = -1 )

Ale ved ti cely cas pisem ze to pretypvat nejde (invalid casting), pretypovat sa neda cokolvek na cokolvek, a za druhe vobec nic pretypovat nepotrebujes pretoze podla tych chybovych hlasok je uplne jasne ze uz ten sprintf vracia typ QString, a teda mas to fromUtf8 uplne odtial vyhodit. Mam to napisat este aj po madarsky?

Nemusis "zabudnut na formatovanie", existuje vela sposobov ako to robit spravne, napr. pomocou .arg, apod, vsetko je v tej nokiackej referencii, dal som ti na nu link kdesi nizsie. najprv si treba precitat celu referenciu nech viem jake ma ta kniznica (triedy v nej) moznosti, az potom robim, a po precitani referencie robim rovno tak, aby to vsetko typovo pasovalo. Si do tej referencie urcite ani nepozrel, ani ked som ti dal link. Viz prispevok hned pod tymto, napriklad tak by to slo aj s makcenom asi, ale ako som pisal ide to vela sposobmi, zaujimave je aj .arg

Ked chces obist obmedzenia sprintf, mozes si napr. urobit pomocou sprintf len to "%d" a zbytok pridat ako UTF8 string, napr.
str = QString::sprintf("%d", den) + QString::fromUtf8(u8". deň v mesiaci");
apod, neskusal som to a vzivote som neprogramoval nokiu, ale teraz citam tu nokiacku referenciu a tak sa programuje, podla toho co je napisane v referencii ze ktora member funkcia co presne robi.

BTW. nejak celkom nechapem co to tam robis s tym
QString::fromUtf8(str.sprintf("%d. deň v roku", den));
ved premennu str naplnis uz tym samotnym sprintf, nie? napr.
str.sprintf("%d. deň v roku", den);
alebo
str = QString::sprintf("%d. deň v roku", den)

Citaj predsa nejaku referenciu, napr. http://doc.qt.nokia.com/latest/qstring.html#sprint f BTW: vsimni si "This function expects a UTF-8 string for %s and Latin-1 for the format string." takze ked to robis takto, tak zas potrebujes Latin1 kodovanie zdrojaku :)

Ten prvý kód úplne hore čo je mi funguje (pomýlil som sa, keď som písal otázku), ale ak miesto reťazca zadám sprintf, kde chcem urobiť formátovaný reťazec, tak mi to neskompiluje. Bolo by dobré, keby to nejaký moderátor opravil prvú vetu takto:

Chybne:
Problém je ten, že ak napíšem niečo takéto, síce to prejde, ale nemám zobrazené znaky s diakritikou:

Správne:
Problém je ten, že ak napíšem niečo takéto, síce to prejde aj sa to správne zobrazí, ale ak miesto reťazca dám metódu sprintf(), tak to nefunguje:

pochopil si to asi blbo, sprintf je pouzitelny na premennu triedy QString a teda tu premennu zrejme rovno aj naplni, t.j. ked pouzijes sprintf tak uz tam nedavaj ziadne fromUTF8 ani nic podobne.

No a dal som ti tusim vyssie link, kde je jasne napisane ze formatovaci string u sprintf musi byt v kodovani Latin1, tak potom mas problem s diakritikou. Ked nechces problemy s diakritikou tak nepouzivaj sprintf vobec ale vid tie linky co som ti dal (alebo si najdi inu referenciu tej nokiackej kniznice, googlom napr. hladas slovo QString)

Ahoj,
jak správně píše MM.., je potřeba použít editor podporující UTF-8 (a soubor uložit jako UTF-8!) nebo použít něco z následujících řešení:

Horší řešení je použít něco jako:

const QString str = QString::fromLocal8Bit("Deň");
ui->lblPopis->setText(str);

Mnohem lepší je pak použít Qt Linguist, kde je možné veškeré řetězce vyskytující se v aplikaci přeložit do libovolného jazyka. Jen je pak nutné s aplikací dodávat i soubor *.qm a ještě před zobrazením hlavního formuláře aplikace správně načíst tento jazykový soubor. To se dělá takto:

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
 
        /** Nacteni systemovych stringu - zobrazuji se napr. v dialogu vyberu souboru, atd. */
	QTranslator qtTranslator;
        qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
        a.installTranslator(&qtTranslator);

        /** Nacteni stringu pro aplikaci, soubor se stringy se jmenuje myapp_{locale}.qm */
        QTranslator myappTranslator;
        myappTranslator.load("myapp_" + QLocale::system().name());
        a.installTranslator(&myappTranslator);

	QMyApp w;
	w.show();
	return a.exec();
}

Soubor *.qm pro českou verzi by byl myapp_cs.qm. Ještě pozor na ty systémové řetězce - v tomto příkladě se soubor obsahující překlady hledá v instalačním adresáři Qt.

EDIT: Po přečtení vlákna vidím, že má odpověď je mimo :-D Takže to prosím ignorujte, možná někomu může přijít zajímavý ten QtLinguist, tak to nemažu.

Podle mě by mělo jít:

QString("%1. deň v roku %2").arg(den).arg(rok)

ale nezkoušel jsem to.

Funkce arg má mnoho přetížení pro QString, jde tam nacpat "libovolný" počet QStringů za sebe.. takže třeba: QString("%1. deň v roku %2").arg(QString("%1").arg(den), QString("%1").arg(rok)) :-D ale to je fuj. Rozhodně doporučuji použít QtLinguist.

A vies vobec co si to urobil? Konvertujes Latin1->Qstring(UTF16)->toASCII->fromUTF8 do QString(UTF16)
Sa divim ze z compileru nevyskocil pri kompilovani boxer :)

P.S. najlepsie je pouzivat .arg priamo pri inicializacii QStringu, tak jak napisal hvezd vyssie priklad (a k tomu asi by bol dobry UTF8 editor alebo mozno u8 pred ten string). potom sa to ale NErobi vsetko v jednom riadku ale v dvoch - najprv inicializujes QString a potom ho niekam priradis.

Áno, neskôr som zistil, že ani to nie je ideálne riešenie a prešiel som na arg(). Musím uznať, s tým to funguje tak ako má.

Doplnené: sprintf() protestoval, ak som okrem int chcel dať ďalší parameter QString. S arg() žiadny problém nebol, len som zistil, že miestami je dokumentácia poslabšia a musel som skúšať metódou pokus omyl. Ale možno sa mýlim a v dokumentácii to je. Nevedel som nájsť čo znamená ktorý znak pre formátovanie reálnych čísel. Pokusmi som zistil, že 'e' je exponent, 'f' je zobrazenie podľa určeného formátovania a 'g' je zobrazenie čísla bez akejkoľvek straty pri desatinných hodnotách.

Zpět do poradny Odpovědět na původní otázku Nahoru