UI
Událost zavření okna
Je potřeba překrýt slot closeWindow. Pokud chceme zablokovat samotné zavření, je potřeba použít ignore na událost:
void MainWindow::closeEvent(QCloseEvent *event)
{
qDebug("closing window...");
event->ignore();
emit finish(); // alternative custom action...
}
Vycentrování okna
Includy:
#include
#include
Umístit kód do konstruktoru okna:
QRect frect = frameGeometry();
frect.moveCenter(QDesktopWidget().availableGeometry().center());
move(frect.topLeft());
http://darkmind2007.blogspot.cz/2009/10/qt-window-in-center-of-screen.html
QString
Kódování - pokud se pracuje s UTF-8 soubory, je potřeba na řetězce ze zdrojáku volat:
QString str = QString::fromUtf8("správně dekódovaný řetězec");
Pro převod řetězců na číslo slouží fce .toInt() apod. Pro převod čísel na řetězce fce QString::number();
QDebug
#include
qDebug() << "Testing";
Vlákna
Staré návody s vytvářením podtříd YThread jsou deprecated. Měla by se vytvářet přímo instance QThread a do ní pak přidat vlastní objekt, který musí být potomkem QObject. Nejlepší návod je na Maya's blogu: How To Really, Truly Use QThreads; The Full Explanation [uloženo].
Komunikace mezi vlákny - každé vláknou má svou event-loop. Pozor na pořadí volání - když zavolám emit f1(); f2(); emit f3(); tak f2 nemá definované pořadí vykonání oproti f1 a f3 (ty půjdou ale zaručené po sobě).
Předávání parametrů:
- odkazem - tam je problém s lockováním - např kód v jednom vlákně if (x != 0) delete x; může selhat, protože mezitím jiné vlákno zrovna x smazalo... Pak stejně jako u referencí nemám přehled kdo všechno má referenci na mlj objekt a kdo mi ho tak může modifikovat
- hodnotou - copy contruktory jsou neefektivní, nemůže se jednoduše pracovat s NULL (0) hodnotou pokud není proměnná nastavena
- reference nejsou dobré z hlediska návrhu - nemám přehled kdo všechno má referenci na mlj objekt a kdo mi ho tak může modifikovat
QTimer - periodické odpalování událostí
Každé odpálení běží ve vlastním vlákně!
Pozor - chová se inteligentně!;-)
Asi nějak kontroluje doběhnutí předchozího volání, protože když dám např. timeout do jeho handleru a ten trvá dýl, než se zavolá handler pro následující QTimer událost, tak ta nová událost s neprovede... Pokus:
QMutex lock;
qDebug("Timer handler called...");
if (!lock.tryLock())
return; // uz je locknuto!
lock.tryLock(2000); // ceka 2 sekundy pak si unlockne
qDebug("End of handler");
Když nastavím timer po např. 0.1 sekundě, tak se stejně vypisují párově obě debugovací hlášky a ne několikrát první a občas druhá, jak bych býval čekal.
EventFilter
Umožňuje trackovat události (myši, klávesnice) nad Qt objekty (zdroj).
Je nezbytný tam, kde nestačí zpracovávat události jen v rámci komponenty - QWidgety s událostni totiž nejsou kompatibilní se signal/slot konceptem (je to vlastnost ;-))!
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast(event);
statusBar()->showMessage(QString("Mouse move (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
}
return false;
}
Pak je potřeba zavolat:
trackedComponent->->installEventFilter(this);
trackedComponent->setMouseTracking(true); // tohle pokud chceme trackovat i pohyb myši
Měření času běhu programu
QTime myTimer;
myTimer.start();
// do something..
int nMilliseconds = myTimer.elapsed();