TIE-11300 Tietotekniikan vaihtuva-alainen kurssi Graafisen käyttöliittymän ohjelmointi Luento 4 Valikot ja dialogit Juha-Matti Vanhatupa
Sisältö Pääikkuna Valikot Dialogit
Pääikkuna (top-level window) Qt:ssa 3 vaihtoehtoa pääikkunan kantaluokaksi: QWidget QMainWindow QDialog
QWidget Kantaluokka UI-komponteille Käytetään sekä pääikkunana, että lapsi-ikkunoina. Voi sisältää toisia komponentteja Sisältää kaikille ikkunoille yhteisiä ominaisuuksia: enabled visible acceptdrops cursor jne.
QMainWindow QWidget:n aliluokka Sisältää: Valikot Työkalupalkin Tilarivin Central widgetin Dock widgetit Central widget voi olla mikä vain QWidget aliluokan olio. Sisältää oletuksena layout:n toisin kuin Qwidget ja QDialog
Valikot Valikoita melkein jokaisessa modernissa sovelluksessa Valikot sisältävät ohjelman käytön kannalta oleelliset toiminnot Usein monta vaihtoehtoista tapaa suorittaa toiminnot
Valikkojen jako Pull-down menut pääikkunan menubar Pop-up menut context menu, right-click menu Työkalupalkki
Qt:n valikot Qt tarjoaa valikoiden ja työkalurivien ohjelmointia helpottamaan QAction luokan. Valikkojen ja työkalupalkkien luonti sisältää seuraavat vaiheet: QAction:ien luonti ja niiden tietojen asetus Valikkojen ja työkalurivien luonti ja yhdistäminen QActioneihin.
QAction Toiminto, joka voidaan liittää valikkoon, mutta myös muihin widgetteihin. Sama instanssi voidaan kytkeä useampaan widgettiin samanaikaisesti. Näin toiminnot pysyvät automaattisesti synkronoituina, jos toiminnon tilaa muutetaan. Toiminto tulee lisätä parent-widgettiin ennen kuin voidaan käyttää, vaikka olisikin globaali.
QAction signaalit void changed () Kutsutaan kun toiminnon tilassa tapahtuu muutos void hovered () Kutsutaan kun jokin toiminto on korostettu (highlight) Esim käyttäjä siirtää hiiren kursorin menu valinnan päälle void toggled ( bool checked ) Kutsutaan, jos toiminnon checked tila muuttuu void QAction::setCheckable ( bool ) void triggered ( bool checked = false ) Kutsutaan kun käyttäjä suorittaa toiminnon
Tapahtumankäsittelijän liittäminen QAction* paction = new QAction( New, this); // Kytketään tapahtumankäsittelijä connect(paction,signal(triggered()),this,slot(onnew())); // Liitetään toiminto tarvittaviin widgetteihin pmenu->addaction(paction); panothermenu->addaction(paction); private void onnew() { // Kutsutaan kun action tapahtuu }
Pikavalinnat QAction* paction = new QAction( Project ); paction->setshortcut(qkeysequence(tr("ctrl+p"))); // TAI paction->setshortcut(qkeysequence(qt::ctrl + Qt::Key_P)));
Alt-tag QAction* fileitem = new QAction( &File ); QAction* newitem = new QAction( &New ); QAction* projectitem = new QAction( &Project );
Esimerkki QActionin luomisesta void MainWindow::createActions() { newaction = new QAction( New, this); newaction->seticon(qicon( :/images/new.png )); newaction->setshortcut(tr("ctrl+n")); newaction->setstatustip(tr( Create new file )); connect(newaction,signal(triggered()),this,slot(newfile()));
Pull-down menu QMenuBar Sisältää listan Pull-down menuja QMainWindow::menuBar ()
Pull-down menu QMenu* filemenu = menubar()->addmenu(tr("&file")); QAction* newact = new QAction(tr("&New"), this); newact->setshortcuts(qkeysequence::new); newact->setstatustip(tr("create a new file")); connect(newact, SIGNAL(triggered()), this, SLOT(onNewFile())); filemenu->addaction(newact);
QMenu Toteuttaa valikon, jota voidaan käyttää pull-down ja pop-up menuissa Valikko sisältää toimintoja Toiminnot lisätään menuun: QAction * QMenu::addAction ( const QString & text ) Periytetty QWidget-luokasta Menun disablointi ja piilottaminen
QMenu signals void abouttoshow () Kutsutaan juuri ennen kuin menu näytetään käyttäjälle void abouttohide () Kutsutaan juuri ennen kuin menu piilotetaan käyttäjältä void hovered ( QAction * action ) Kutsutaan kun jokin toiminto on korostettu (highlight) Esim käyttäjä siirtää hiiren kursorin menu valinnan päälle void triggered ( QAction * action ) Kutsutaan kun käyttäjä suorittaa toiminnon
Hierarkisuus Menuihin voidaan toteuttaa hierarkinen rakenne lisäämällä alimenuja QMenu* filemenu = menubar()->addmenu(tr("file")); QMenu* submenu = filemenu->addmenu(tr( New"));
Valikon päivittäminen Milloin päivittää valikon tila? Vaihtoehto 1: Ohjelma tarkkailee tilaansa ja päivittää valikon heti kun ohjelman tila muuttuu Vaihtoehto 2: Valikko päivitetään vasta sitten kun se avataan
On-Off (checked) QAction* projectitem = new QAction( &Project ); projectitem->setcheckable(true); // Oletuksena pois päältä projectitem->setchecked(true);
QActionGroup Hyödyllinen, jos checked actionit ovat riippuvaisia toistensa tilasta Jos yksi ryhmän toiminto valitaan, niin loput menevät automaattisesti pois päältä (exclusive) Hyödyllinen, jos sama toiminto halutaan suorittaa useammalle actionille QActionGroup::setDisabled ( bool b )
QActionGroup alignmentgroup = new QActionGroup(this); alignmentgroup->addaction(leftalignact); alignmentgroup->addaction(rightalignact); alignmentgroup->addaction(justifyact); alignmentgroup->addaction(centeract); leftalignact->setchecked(true);
Separator Erotinviiva, jonka avulla voidaan ryhmitellä toimintoja Toteutetaan QAction luokan avulla QAction* pseparator = new QAction(); pseparator->setseparator(true); pmenu->addaction(pseparator);
Pop-up menu QMenu Toimii myös pop-up menuna
Pop-up menu QMenu* popupmenu = new QMenu(); popupmenu->addaction( Copy ); popupmenu->addaction( Cut ); popupmenu->addaction( Paste ); // Avataan menu synkronisesti popupmenu->exec(qcursor::pos()); // TAI asynkronisesti popupmenu->popup(qcursor::pos());
QWidget ja QAction Myös widgetti voi sisältää listan actioneja QWidget::addAction ( QAction * action ) Qlist<QAction *> QWidget::actions () const ContextMenuPolicy Kertoo miten widgetti näyttää context menun
ContextMenuPolicy Enum Qt::NoContextMenu Parent widget huolehtii context menusta Qt::PreventContextMenu Ei context menua Qt::DefaultContextMenu Kutsutaan ContextMenuEvent eventtiä Qt::ActionsContextMenu Muodostetaan menu widgetin actioneista Qt::CustomContextMenu Emitoidaan custom context menu signaali QWidget::customContextMenuRequested ( const QPoint & pos ) pos = widgetin koordinaatit
QToolBar Työkalupalkki, johon voi lisätä QActiontyyppisiä toimintoja Toiminnot näytetään painikkeina (QToolButton) void QMainWindow::addToolBar ( QToolBar * toolbar )
QToolBar QToolBar* ptoolbar = new QToolBar( test bar ); QAction* paction = new QAction( test item ); // Lisää toiminto työkalupalkkiin ptoolbar->addaction(paction); // Liitä työkalupalkki pääikkunaan addtoolbar(ptoolbar);
QToolButton Esittää QActionin painikkeena enum Qt::ToolButtonStyle Qt::ToolButtonIconOnly (default) Qt::ToolButtonTextOnly Qt::ToolButtonTextBesideIcon Qt::ToolButtonTextUnderIcon
QStatusBar Voidaan asettaa (korvata) setstatusbar() funktiolla. Jos ei asetettu, tyhjä statusbar palautetaan kun statusbar() funktiota kutsutaan Ilmoituksia kolmea tyyppiä: - Tilapäinen Temporary Tilapäinen viesti näytetään status barissa. Voi piilottaa normaalin status barin tekstin. - Normaali Normal Esimerkiksi sivun ja rivin numerot tekstinkäsittelyohjelmassa. - Pysyvä Permanent Ei piiloteta koskaan. Käytetään tärkeille ilmoituksille, esimerkiksi Caps Lock:n päällä olo voidaan näyttää.
QStatusBar Tilapäinen viesti: statusbar()->showmessage(tr( Ready! )); Lyhytaikainen viesti voidaan poistaa kutsumalla clearmessage tai antaa aikaraja parametrina showmessage funktiokutsussa.
QStatusBar QStatusBar* pstatusbar = new QStatusBar(); // Normal widget vasempaan reunaan pstatusbar->insertwidget(0,pwidget); // Permanent widget oikeaan reunaan pstatusbar->insertpermanentwidget(0,pwidget2); // Liitä tilarivi pääikkunaan addtoolbar(pstatusbar );
Dialogit Käytetään yleensä lyhytaikaisessa kommunikoinnissa käyttäjän kanssa. Top-level ikkuna, mutta sisältää parentin toisin kuin muut top-level ikkunat. Dialogi aukeaa oletuksena parentin keskelle. Modaalinen dialogi blokkaa parent-ikkunan käytön.
Dialogisuunnittelun haasteita 1. Dialogin selkeä rakenne Rymittele komponentit selkeästi (rivit, sarakkeet, ryhmät (groupbox)) Jaa kokonaisuus useampaan osaan (välilehdet) Noudata annettuja tyyliohjeita Esim Windows User Experience Interaction Guidelines http://msdn.microsoft.com/en-us/library/aa511258.aspx 2. Ikkunan koon muutokset (skaalautuvuus) Suunnittele miten komponentit venyvät, kun ikkunan kokoa muutetaan 3. UI-tekstien muutokset (esim lokalisointi, riittääkö tila kun kieli vaihtuu?) Varaa riittävästi tilaa UI-teksteille Fontin koon muutos?
Esimerkki-dialogi
QDialog QDialog* dialog = new QDialog(); dialog->show(); // ei-modaalinen dialog->exec(); // modaalinen dialog->setmodal(true); dialog->show(); // modaalinen
QDialog Voi antaa paluuarvon (DialogCode) QDialog::Accepted QDialog::Rejected Voi sisältää oletusnäppäimiä: määrittää mitä toimintoa enter-näppäin vastaa dialogissa QPushButton::setDefault
QColorDialog QErrorMessage QFileDialog QFontDialog QInputDialog QPageSetupDialog QPrintPreviewDialog QProgressDialog QWizard Qt:n valmisdialogit
Lightbox Tekniikka, jossa käyttäjän huomio pakotetaan modaaliin dialogiin tummentamalla tausta. Käytetään web-käyttöliittymissä tai kuvagallerioissa. Haittoja: - Pakottaa käyttäjän todella keskeyttämään kaiken muun, joten ei tule käyttää turhaan. - Taustalla voi olla näkyvissä tietoja, joita tarvittaisiin tekemään päätös dialogissa.
QMessageBox Modaalinen dialogi, jolla voidaan näyttää yksinkertaisia ilmoituksia tai kysymyksiä käyttäjälle. QMessageBox msgbox; msgbox.settext("the document has been modified."); msgbox.exec();
QMessageBox Voidaan esittää myös kysymyksiä QMessageBox::StandardButton QMessageBox msgbox; msgbox.settext("the document has been modified."); msgbox.setinformativetext("do you want to save your changes?"); msgbox.setstandardbuttons(qmessagebox::save QMessageBox::Discard QMessageBox::Cancel); msgbox.setdefaultbutton(qmessagebox::save); int ret = msgbox.exec();
Omien käyttöliittymäkomponenttien teko Periytetään kantaluokasta Käytetään joko suoraan koodista tai QDesignerissa promote to -toiminnalla.
Tab järjestys Tabulaattori-näppäimellä voidaan vaihtaa fokus seuraavaan lapsi-ikkunaan. Focus policy arvolla voidaan määritellä ikkunan fokus-arvo. QWidget (static) void settaborder ( QWidget * first, QWidget * second ) Qt::FocusPolicy Qt::TabFocus Qt::ClickFocus Qt::StrongFocus (TabFocus ClickFocus) Qt::WheelFocus Qt::NoFocus