Advanced Services | QMainWindow - QStatusBar - QMenuBar - QFileDialog - QImage - QScrollArea |
Wie im vorigen Kapitel legen wir auch hier im QtCreator immer ein leeres Qt4 Projekt an. Wir verwenden nun aber an Stelle eines QWidget ein QMainWindow als Hauptfenster.
Wir überschreiben die Methode void MainWindow::resizeEvent(QResizeEvent * event) und fragen die Größe des Hauptfensters ab. Die ermittelte Größe wird der selbstgeschriebenen Methode sizeChanged() übergeben, die dann die Größe auf ein QLabel ausgibt. Hier ist kein signal/slot Eventhandling notwendig. Da wir keine Slotmethode schreiben brauchen wir auch das Q_OBJECT Makro nicht. Auch die Methode sizeChanged() kann man sich sparen, wenn man ihren Code direkt in resizeEvent() implementiert.
/* intermediate01.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QLabel> class MainWindow : public QMainWindow { // Q_OBJECT wird hier nicht gebraucht private: QLabel* label; int counter; void initMainWindow(); void resizeEvent( QResizeEvent * event ); void sizeChanged(QSize& size); public: MainWindow(QWidget *parent = 0); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" // konstruktor MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { counter = 0; initMainWindow(); } void MainWindow::initMainWindow() { this->setWindowTitle("this is intermediate01"); this->setGeometry(40, 30, 280, 180); // hintergrundfarbe für hauptfenster QPalette pal1(this->palette()); QColor bgColor(180,190,200, 255); // r,g,b,a pal1.setColor(QPalette::Background, bgColor); this->setPalette(pal1); // label direkt in das mainwindow label = new QLabel(this); label->setAutoFillBackground(true); label->setFont(QFont("Times", 13, QFont::Bold)); label->setText("hi"); label->setGeometry(QRect(40, 30, 200, 50)); label->setFrameStyle( QFrame::Panel | QFrame::Sunken ); // hintergrundfarbe für das label QPalette labPal(label->palette()); QColor bgCol(200,190,180, 255); // r,g,b,a labPal.setColor(QPalette::Background, bgCol); label->setPalette(labPal); } // overriding void MainWindow::resizeEvent(QResizeEvent * event) { QMainWindow::resizeEvent(event); QSize size = this->size(); this->sizeChanged(size); } void MainWindow::sizeChanged(QSize& size) { QString width, height; width.setNum(size.width()); height.setNum(size.height()); label->setText("width= " + width + " height = " + height); } /* main.cpp in diesem beispiel wird das QMainWindow wie ein normales QWidget verwendet. Es wird lediglich ein QLabel in das QMainWindow aufgenommen. wir reagieren auf ein größenänderung des fensters. dazu wird die methode void MainWindow::resizeEvent(QResizeEvent * event) überschrieben. in ihr wird die methode sizeChanged(QSize size) aufgerufen, der die neue größe übergeben wird und diese auf das label ausgibt. ein signal/slot eventhandling wird hier nicht gebraucht siehe mainwindow.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Das Beispiel ist analog zum vorigen, nur wird die Größenänderung jetzt in der Statuszeile ausgegeben.
Das QLabel ist somit überflüssig.
Achtung:
Die Methode showMessage() von QStatusbar ist nur für temporäre Meldungen gedacht. Wie man permanente
Meldunge auf die QStatusbar bringt wird im Beispiel 7 erklärt.
/* mainwindow.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> class MainWindow : public QMainWindow { private: QWidget *centralWidget; QStatusBar *statusBar; int counter; void initMainWindow(); void resizeEvent(QResizeEvent* event); void sizeChanged(const QSize&); public: MainWindow(QWidget *parent = 0); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" // konstruktor MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { counter = 0; initMainWindow(); } void MainWindow::initMainWindow() { this->setWindowTitle("this is intermediate02"); this->setGeometry(40, 30, 280, 180); // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(180,190,200, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); // statuslabel statusBar = new QStatusBar(); this->setStatusBar(statusBar); // notwendig !! statusBar->setObjectName(QString::fromUtf8("statusBar")); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->showMessage("Statuszeile"); statusBar->setAutoFillBackground(true); // farbe für das statuslabel QPalette statusPalette(statusBar->palette()); QColor grau(190,210,200, 255); // r,g,b,a statusPalette.setColor(QPalette::Background, grau); statusBar->setPalette(statusPalette); } void MainWindow::resizeEvent(QResizeEvent* event) { QMainWindow::resizeEvent(event); QSize size = this->size(); sizeChanged(size); } void MainWindow::sizeChanged(const QSize& qSize) { int height = qSize.height(); int width = qSize.width(); QString hei, wid, count; wid.setNum(width); hei.setNum(height); statusBar->showMessage("width = " + wid + " height = " + hei); } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Ein QMainWindow hat deutlich mehr Möglichkeiten als ein QWidget. Neben einer Statuszeile kann ein QMainWindow eine Menuzeile und eine Toolbar besitzen. des weiteren gibt es ein zentrales QWidget, das als Behälter für weitere QKomponenten fungiert. Hat man bewegliche Komponenten wie etwa eine Toolbar, so weicht beim Verschieben der Toolbar das zentrale Widget aus. Dies kann man an dem folgenden Beispiel sehen.
Nur die ToolBar wird "geaddet", die restlichen Methode sind set-Methoden !
Zu diesen Methoden gibt es keine get-Methoden, d.h., es gibt keine default Menüzeile etc.
Man muß alle diese Komponenten selbst erzeugen. Hat man keine bewegliche Komponenten
so kann man die Komponenten auch direkt in das QMainWindow plazieren.
Das folgende Beispiel hat neben einer beweglichen ToolBar einen Button im zentralen Widget mit
dem man die Statuszeile ein- und ausblenden kann. Auf den Screenshots sieht man an der
veränderten Position des Buttons, wie das zentrale Widget der Toolbar ausweicht.
/* mainwindow.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QPushButton> #include <QStatusBar> #include <QToolBar> class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QPushButton *pushButton; QStatusBar *statusBar; int counter; void initMainWindow(); void initStatusBar(); void initToolBar(); public: MainWindow(QWidget *parent = 0); public slots: void toggleStatusBar(); void inc(); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { counter = 0; initMainWindow(); initStatusBar(); initToolBar(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); // hauptfenster konfigurieren this->setWindowTitle("intermediate03"); this->resize(240, 170); //zentrales QWidget einrichten centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); //QPushButton pushButton = new QPushButton(centralWidget); pushButton->setFont(QFont("Times", 18, QFont::Bold)); pushButton->setText("hide status bar"); pushButton->setObjectName(QString::fromUtf8("pushButton")); pushButton->setGeometry(QRect(40, 30, 160, 40)); pushButton->setFlat(true); // false ist default pushButton->setAutoFillBackground(true); // farbe für den text des buttons QPalette buttonpalette(pushButton->palette()); QColor buttonTextColor(170,30,30, 255); // r,g,b,a buttonpalette.setColor(QPalette::ButtonText, buttonTextColor); pushButton->setPalette(buttonpalette); //sender-empfänger-verbindung QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT( toggleStatusBar() ) ); QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT( inc() ) ); // QObject kann weggelassen werden } void MainWindow::initStatusBar() { // QStatusBar statusBar = new QStatusBar(this); this->setStatusBar(statusBar); statusBar->setObjectName(QString::fromUtf8("statusBar")); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->showMessage("Statuszeile"); statusBar->setAutoFillBackground(true); QPalette statusPalette(statusBar->palette()); QColor grau(220,220,220, 255); // r,g,b,a statusPalette.setColor(QPalette::Background, grau); statusBar->setPalette(statusPalette); } void MainWindow::initToolBar() { QToolBar* qToolBar = new QToolBar(); qToolBar->setAutoFillBackground(true); this->addToolBar(qToolBar); } //slot void MainWindow::inc() { QString text; text.setNum(++counter); statusBar->showMessage("clicks: " + text); } //slot void MainWindow::toggleStatusBar() { if( statusBar->isHidden() ) { pushButton->setText("hide statusbar"); statusBar->show(); } else { pushButton->setText("show statusbar"); statusBar->hide(); } } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Das Ein- und Ausblenden der Statuszeile wird nun über ein Menüitem gesteuert.
/* mainwindow.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> #include <QToolBar> #include <QLabel> //#include <QMenu> //nicht notwendig class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QMenuBar *menuBar; QStatusBar *statusBar; QAction* showAction ; QLabel* label; void initMainWindow(); void initMenuBar(); public: MainWindow(QWidget *parent = 0); public slots: void toggleAction(); void messageAction(); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { initMainWindow(); initMenuBar(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); //einrichten des hauptfensters this->setWindowTitle("intermediate04"); this->resize(280, 180); centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); // label in das zentrale widget label = new QLabel(centralWidget); label->setAutoFillBackground(true); label->setFont(QFont("Times", 14, QFont::Bold)); label->setText("hi"); label->setGeometry(QRect(40, 40, 165, 50)); label->setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QStatusBar statusBar = new QStatusBar(this); statusBar->setObjectName(QString::fromUtf8("statusBar")); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->showMessage("Statuszeile"); //statusBar->setFrameStyle( QFrame::Panel | QFrame::Sunken ); methode gibt es nicht statusBar->setAutoFillBackground(true); // farbe für QStatusBar QPalette pal3(statusBar->palette()); QColor grau(220,230,240, 255); // r,g,b,a pal3.setColor(QPalette::Background, grau); statusBar->setPalette(pal3); this->setStatusBar(statusBar); } void MainWindow::initMenuBar() { // QMenuBar (einrichten der menuzeile) menuBar = new QMenuBar(); this->setMenuBar(menuBar); // eine leere menubar wird nicht angezeigt // filemenu QMenu* fileMenu = menuBar->addMenu(tr("&file")); // QAction für das filemenu (eine QAction entspricht einem menuitem, das signale senden kann) QAction* closeAction = new QAction("exit", this); closeAction->setShortcut(tr("Ctrl+X")); // setShortcut will eine QKeySequence, deswegen das makro tr //closeAction->setStatusTip(tr("Close Program")); fileMenu->addAction(closeAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); // showmenu QMenu* showMenu = menuBar->addMenu(tr("&show")); // diese QAction muß membervariable sein, weil wir in toggleAction darauf zugreifen müssen showAction = new QAction("hide statusbar", this); showAction->setShortcut(tr("Ctrl+T")); showMenu->addAction(showAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(showAction, SIGNAL(triggered()), this, SLOT(toggleAction())); // clicked man auf den menueintrag in der menubar, so wird ein aboutToShow-signal gesendet ! QObject::connect(showMenu, SIGNAL(aboutToShow()), this, SLOT(messageAction())); } //slot void MainWindow::toggleAction() { if( statusBar->isHidden() ) { //pushButton->setText("hide statusbar"); showAction->setText("hide statusbar"); label->setText("statusbar is visible"); statusBar->show(); } else { //pushButton->setText("show statusbar"); showAction->setText("show statusbar"); label->setText("statusbar is hidden"); statusBar->hide(); } } //slot void MainWindow::messageAction() { statusBar->showMessage("du bist auf dem show menu"); } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Das Beispiel zeigt die Handhabung des QtFileDialogs. Dieser kann in zwei verschiedenen Formen erscheinen, mit plattformunabhängigen Qt-Design oder es öffnet sich der BetriebssystemFileDialog.
QFileDialog* fileDialog = new QFileDialog(mainWindow); fileDialog->show();
mit show() erscheint der Qt-eigene Filedialog. In diesem Fall braucht man signal-slot-eventhandling um an den Dateinamen heranzukommen.
QObject::connect(fileDialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileHandler(const QString&))); void MainWindow::fileHandler(const QString& fileName) { label->setText(fileName); }
QFileDialog* fileDialog = new QFileDialog(mainWindow); QString fileName = fileDialog->getOpenFileName(this);
Die Methode getOpenFileName öffnet den BetriebssystemFileDialog, in diesem Beispiel also den WindowsFileDialog. Vorteil ist, daß man hier den Dateinamen sofort bekommt.
In dem folgenden Beispiel hat man im Filemenu die Wahl zwischen den beiden Dialogformen. Der ausgewählte Dateiname erscheint in einem QLabel.
/* mainwindow.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> #include <QFileDialog> #include <QMenuBar> #include <QLabel> //#include <QMenu> //nicht notwendig class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QMenuBar *menuBar; QStatusBar *statusBar; QAction* showAction ; QLabel* label; QFileDialog* fileDialog; void initMainWindow(); void initMenuBar(); void initFileDialog(); public: MainWindow(QWidget *parent = 0); public slots: void toggleAction(); void messageAction(); void openQtDialog(); void openWinDialog(); void fileHandler(const QString&); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { initMainWindow(); initMenuBar(); initFileDialog(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); //einrichten des hauptfensters this->setWindowTitle("intermediate04"); this->resize(450, 200); centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); // label in das zentrale widget label = new QLabel(centralWidget); label->setAutoFillBackground(true); label->setFont(QFont("Times", 13, QFont::Bold)); label->setText("hi"); label->setGeometry(QRect(30, 50, 390, 50)); label->setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QStatusBar statusBar = new QStatusBar(this); statusBar->setObjectName(QString::fromUtf8("statusBar")); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->showMessage("Statuszeile"); //statusBar->setFrameStyle( QFrame::Panel | QFrame::Sunken ); methode gibt es nicht statusBar->setAutoFillBackground(true); // farbe für QStatusBar QPalette statusPalette(statusBar->palette()); QColor grau(220,230,240, 255); // r,g,b,a statusPalette.setColor(QPalette::Background, grau); statusBar->setPalette(statusPalette); this->setStatusBar(statusBar); } void MainWindow::initMenuBar() { // QMenuBar (einrichten der menuzeile) menuBar = new QMenuBar(); menuBar->setObjectName(QString::fromUtf8("menuBar")); menuBar->setGeometry(QRect(0, 0, 300, 18)); this->setMenuBar(menuBar); // eine leere menubar wird nicht angezeigt // openmenu QMenu *fileMenu = new QMenu(); fileMenu = menuBar->addMenu(tr("&file")); // qtOpenAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* qtOpenAction = new QAction("open Qt dialog", this); qtOpenAction->setShortcut(tr("Ctrl+O")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(qtOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(qtOpenAction, SIGNAL(triggered()), this, SLOT(openQtDialog())); // winOpenAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* winOpenAction = new QAction("open MS dialog", this); winOpenAction->setShortcut(tr("Ctrl+W")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(winOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(winOpenAction, SIGNAL(triggered()), this, SLOT(openWinDialog())); // exitAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* closeAction = new QAction("exit", this); closeAction->setShortcut(tr("Ctrl+X")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(closeAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); // showmenu QMenu *showMenu = new QMenu(); showMenu = menuBar->addMenu(tr("&show")); // QAction für das showmenu (eine QAction ist ein menuitem, das signale senden kann) // muß membervariable sein, weil wir in toggleAction darauf zugreifen müssen showAction = new QAction("hide statusbar", this); showAction->setShortcut(tr("Ctrl+T")); showMenu->addAction(showAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(showAction, SIGNAL(triggered()), this, SLOT(toggleAction())); // clicked man auf den menueintrag in der menubar, so wird ein aboutToShow-signal gesendet ! QObject::connect(showMenu, SIGNAL(aboutToShow()), this, SLOT(messageAction())); } void MainWindow::initFileDialog() { fileDialog = new QFileDialog(this); // nur notwendig für den qt-filedialog QObject::connect(fileDialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileHandler(const QString&))); } //slot void MainWindow::openQtDialog() { // bringt einen qt4 filedialog fileDialog->show(); } //slot void MainWindow::openWinDialog() { // getOpenFileName bringt den windowsfiledialog QString fileName = fileDialog->getOpenFileName(this); label->setText(fileName); } //slot void MainWindow::fileHandler(const QString& fileName) { label->setText(fileName); } //slot void MainWindow::toggleAction() { if( statusBar->isHidden() ) { showAction->setText("hide statusbar"); label->setText("statusbar is visible"); statusBar->show(); } else { showAction->setText("show statusbar"); label->setText("statusbar is hidden"); statusBar->hide(); } } //slot void MainWindow::messageAction() { statusBar->showMessage("du bist auf dem show menu"); //label->setText("show menu"); } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Es wird der Qt-FileDialog gezeigt.
In Erweiterung des vorigen Beispiels wird gezeigt, wie man eine Bilddatei in Qt anzeigen kann. Man beachte den roten Text in mainwindow.cpp.
/* mainwindoow.h */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> #include <QFileDialog> #include <QMenuBar> #include <QLabel> class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QMenuBar *menuBar; QStatusBar *statusBar; QAction* showAction ; QLabel* label; QFileDialog* fileDialog; int counter; void initMainWindow(); void initMenuBar(); void initFileDialog(); public: MainWindow(QWidget *parent = 0); public slots: void toggleAction(); void openQtDialog(); void openWinDialog(); void fileHandler(const QString&); }; #endif // MAINWINDOW_H /* mainwindoow.cpp */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { counter = 0; initMainWindow(); initMenuBar(); initFileDialog(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); //einrichten des hauptfensters this->setWindowTitle("intermediate06"); this->resize(380, 480); centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); // label in das zentrale widget label = new QLabel(centralWidget); label->setAutoFillBackground(true); label->setFont(QFont("Times", 13, QFont::Bold)); label->setText("hi"); label->setGeometry(QRect(30, 30, 320, 375)); label->setFrameStyle( QFrame::Panel | QFrame::Sunken ); // QStatusBar statusBar = new QStatusBar(this); statusBar->setObjectName(QString::fromUtf8("statusBar")); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->showMessage("Statuszeile"); //statusBar->setFrameStyle( QFrame::Panel | QFrame::Sunken ); methode gibt es nicht statusBar->setAutoFillBackground(true); // farbe für QStatusBar QPalette pal3(statusBar->palette()); QColor grau(220,230,240, 255); // r,g,b,a pal3.setColor(QPalette::Background, grau); statusBar->setPalette(pal3); this->setStatusBar(statusBar); } void MainWindow::initMenuBar() { // QMenuBar (einrichten der menuzeile) menuBar = new QMenuBar(); menuBar->setObjectName(QString::fromUtf8("menuBar")); menuBar->setGeometry(QRect(0, 0, 300, 18)); this->setMenuBar(menuBar); // eine leere menubar wird nicht angezeigt // openmenu QMenu *fileMenu = new QMenu(); fileMenu = menuBar->addMenu(tr("&file")); // qtOpenAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* qtOpenAction = new QAction("open Qt dialog", this); qtOpenAction->setShortcut(tr("Ctrl+O")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(qtOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(qtOpenAction, SIGNAL(triggered()), this, SLOT(openQtDialog())); // winOpenAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* winOpenAction = new QAction("open MS dialog", this); winOpenAction->setShortcut(tr("Ctrl+W")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(winOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(winOpenAction, SIGNAL(triggered()), this, SLOT(openWinDialog())); // exitAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* closeAction = new QAction("exit", this); closeAction->setShortcut(tr("Ctrl+X")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(closeAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); // showmenu QMenu *showMenu = new QMenu(); showMenu = menuBar->addMenu(tr("&show")); // QAction für das showmenu (eine QAction ist ein menuitem, das signale senden kann) // muß membervariable sein, weil wir in toggleAction darauf zugreifen müssen showAction = new QAction("hide statusbar", this); showAction->setShortcut(tr("Ctrl+T")); showMenu->addAction(showAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(showAction, SIGNAL(triggered()), this, SLOT(toggleAction())); } void MainWindow::initFileDialog() { fileDialog = new QFileDialog(this); // nur notwendig für den qt-filedialog QObject::connect(fileDialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileHandler(const QString&))); } //slot void MainWindow::openQtDialog() { // bringt einen qt4 filedialog fileDialog->show(); } //slot void MainWindow::openWinDialog() { // getOpenFileName bringt den windowsfiledialog QString fileName = fileDialog->getOpenFileName(this); QImage* qImage = new QImage(fileName); label->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); } //slot void MainWindow::fileHandler(const QString& fileName) { QImage* qImage = new QImage(fileName); label->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); } //slot void MainWindow::toggleAction() { if( statusBar->isHidden() ) { showAction->setText("hide statusbar"); statusBar->show(); } else { showAction->setText("show statusbar"); statusBar->hide(); } } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Das Beispiel ist eine Erweiterung des vorigen Beispiels. Man möchte natürlich, daß sich das QLabel mit dem Bild auch vergrößert wenn man das Mainwindow vergrößert. Dieses Beispiel löst diese Aufgabe und arbeitet dazu die Ergebnisse von Beispiel 1 ein.
Die Methode showMessage() aus QStatusBar ist nur für temporäre Meldungen gedacht. Fährt man mit dem
Mauszeiger z.Bsp über die Menuleiste so verschwindet diese Meldung um evtl. anderen Meldungen Platz zu machen.
Will man permanente Meldungen in der Statuszeile, so muß man die Statuszeile um eine QLabel ergänzen und dieses Label
mit der Methode statusBar->addPermanentWidget(permanentLabel, 1); in die Statusbar aufnehmen. Der Parameter 1
bedeutet, daß das Label linksbündig plaziert wird und so die temporäre Meldung ersetzt (siehe Kommentar im Code).
/* mainwindoow.h intermediate07 fortsetzung von intermediate06 */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> #include <QFileDialog> #include <QMenuBar> #include <QLabel> class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QMenuBar *menuBar; QStatusBar *statusBar; QAction* showAction ; QLabel* imageLabel; QLabel* permanentLabel; QFileDialog* fileDialog; int border; void initMainWindow(); void initMenuBar(); void initFileDialog(); void resizeEvent(QResizeEvent * e); void sizeChanged(QSize& size); public: MainWindow(QWidget *parent = 0); public slots: void toggleAction(); void openQtDialog(); void openWinDialog(); void fileHandler(const QString&); }; #endif // MAINWINDOW_H /* mainwindow.cpp fortsetzung von intermediate06 beim aus- oder einblenden der statuszeile wird die fenstergröße abgeholt und die methode sizeChanged() aufgerufen. der dateiname einschließlich pfad des bildes wird in der statuszeile permanent ausgegeben. das bild zentriert man mit: label->setAlignment(Qt::AlignCenter); */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { border = 10; initMainWindow(); initMenuBar(); initFileDialog(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); //einrichten des hauptfensters this->setWindowTitle("intermediate07"); this->resize(380, 480); // anlegen des zentralen widgets centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); // label in das zentrale widget legen imageLabel = new QLabel(centralWidget); imageLabel->setAutoFillBackground(true); imageLabel->setFont(QFont("Times", 13, QFont::Bold)); imageLabel->setText("hi"); imageLabel->setGeometry(QRect(20, 20, 340, 420)); imageLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); imageLabel->setAlignment(Qt::AlignCenter); // QStatusBar statusBar = new QStatusBar(this); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->setAutoFillBackground(true); //statusBar->showMessage("temporarily"); //Note that showMessage() is called to show temporary explanations of tool tip texts, //so passing a timeout of 0 is not sufficient to display a permanent message. // permanente meldunge erreicht man nur, wenn man ein eigenes label erzeugt und mit // addPermanentWidget in die statusbar aufnimmt. // label für permanente meldungen in der statuszeile permanentLabel = new QLabel(); statusBar->addPermanentWidget(permanentLabel, 1); permanentLabel->setText("für permanente meldungen"); // parameter 0 bedeutet, daß das label auf der rechten seite links vom anfasser plaziert wird // und somit zwei meldungen angezeigt werden, die temporäre und die permanente // parameter 1 bedeutet, daß das label auf der linken seite angezeigt wird und somit // die temporäre meldung nicht mehr angezeigt wird // farbe für QStatusBar QPalette statusPalette(statusBar->palette()); QColor grau(220,230,240, 255); // r,g,b,a statusPalette.setColor(QPalette::Background, grau); statusBar->setPalette(statusPalette); this->setStatusBar(statusBar); } void MainWindow::initMenuBar() { // QMenuBar (einrichten der menuzeile) menuBar = new QMenuBar(); menuBar->setObjectName(QString::fromUtf8("menuBar")); menuBar->setGeometry(QRect(0, 0, 300, 18)); this->setMenuBar(menuBar); // eine leere menubar wird nicht angezeigt // openmenu QMenu *fileMenu = new QMenu(); fileMenu = menuBar->addMenu(tr("&file")); // qtOpenAction // QAction für das filemenu (eine QAction ist ein menuitem, das signale senden kann) QAction* qtOpenAction = new QAction("open Qt dialog", this); qtOpenAction->setShortcut(tr("Ctrl+O")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(qtOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(qtOpenAction, SIGNAL(triggered()), this, SLOT(openQtDialog())); // winOpenAction QAction* winOpenAction = new QAction("open MS dialog", this); winOpenAction->setShortcut(tr("Ctrl+W")); fileMenu->addAction(winOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(winOpenAction, SIGNAL(triggered()), this, SLOT(openWinDialog())); // exitAction QAction* closeAction = new QAction("exit", this); closeAction->setShortcut(tr("Ctrl+X")); fileMenu->addAction(closeAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); // showmenu QMenu *showMenu = new QMenu(); showMenu = menuBar->addMenu(tr("&show")); // muß membervariable sein, weil wir in toggleAction darauf zugreifen müssen showAction = new QAction("hide statusbar", this); showAction->setShortcut(tr("Ctrl+T")); showMenu->addAction(showAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(showAction, SIGNAL(triggered()), this, SLOT(toggleAction())); } void MainWindow::initFileDialog() { fileDialog = new QFileDialog(this); // nur notwendig für den qt-filedialog QObject::connect(fileDialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileHandler(const QString&))); } // overriding void MainWindow::resizeEvent(QResizeEvent * e) { QMainWindow::resizeEvent(e); QSize size = this->size(); this->sizeChanged(size); } void MainWindow::sizeChanged(QSize& size) { int statusBarHeight = statusBar->size().height(); int menuBarHeight = menuBar->size().height(); if( statusBar->isHidden()) imageLabel->setGeometry(QRect(border, border, size.width()- 2*border, size.height()- (2*border + menuBarHeight) )); // notwendig else imageLabel->setGeometry(QRect(border, border, size.width()- 2*border, size.height()-(2*border + menuBarHeight + statusBarHeight) )); // notwendig } //slot void MainWindow::openQtDialog() { // bringt einen qt4 filedialog fileDialog->show(); } //slot void MainWindow::openWinDialog() { // getOpenFileName bringt den windowsfiledialog QString fileName = fileDialog->getOpenFileName(this); QImage* qImage = new QImage(fileName); imageLabel->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); permanentLabel->setText(fileName); } //slot void MainWindow::fileHandler(const QString& fileName) { QImage* qImage = new QImage(fileName); imageLabel->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); permanentLabel->setText(fileName); } //slot void MainWindow::toggleAction() { if( statusBar->isHidden() ) { showAction->setText("hide statusbar"); statusBar->show(); } else { showAction->setText("show statusbar"); statusBar->hide(); } QSize size = this->size(); this->sizeChanged(size); } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
QScrollArea kann das zentrale Widget nicht ersetzen sondern muß in dieses aufgenommen werden. Da wir kein Layout verwenden muß die die Größenanpassung der QScrollArea an das Mainwindow von Hand in der Methode sizeChanged() vorgenommen werden. Die automatische Größenanpassung des Imagelabels in der Scrollarea erreicht man mit scrollArea->setWidgetResizable(true);
/* mainwindoow.h intermediate08 fortsetzung von intermediate07 */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStatusBar> #include <QFileDialog> #include <QMenuBar> #include <QLabel> #include <QScrollAreaglt; class MainWindow : public QMainWindow { Q_OBJECT private: QWidget *centralWidget; QMenuBar *menuBar; QStatusBar *statusBar; QAction* showAction ; QLabel* imageLabel; QLabel* permanentLabel; QFileDialog* fileDialog; QScrollArea* scrollArea; int border; void initMainWindow(); void initMenuBar(); void initFileDialog(); void resizeEvent(QResizeEvent * e); void sizeChanged(QSize& size); public: MainWindow(QWidget *parent = 0); public slots: void toggleAction(); void openQtDialog(); void openWinDialog(); void fileHandler(const QString&); }; #endif // MAINWINDOW_H /* mainwindow.cpp */ #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { border = 10; // 10 pixel rand um die scrollarea initMainWindow(); initMenuBar(); initFileDialog(); } void MainWindow::initMainWindow() { // hintergrundfarbe für hauptfenster QPalette mainPalette(this->palette()); QColor bgColor(150,160,170, 255); // r,g,b,a mainPalette.setColor(QPalette::Background, bgColor); this->setPalette(mainPalette); //einrichten des hauptfensters this->setWindowTitle("intermediate08"); this->resize(400, 400); // zentrales widget setzen // die scrollarea als zentrales widget zu setzen funzt nicht centralWidget = new QWidget(this); centralWidget->setObjectName(QString::fromUtf8("centralWidget")); this->setCentralWidget(centralWidget); // imageLabel für die scrollarea imageLabel = new QLabel(); //imageLabel->setAutoFillBackground(true); imageLabel->setFont(QFont("Times", 13, QFont::Bold)); imageLabel->setText("hi"); imageLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken ); imageLabel->setAlignment(Qt::AlignCenter); // scrollarea anlegen, widget aufnehmen scrollArea = new QScrollArea(centralWidget); scrollArea->setWidgetResizable(true); // wichtig, damit die größe des imageLabels in der scrollarea automatisch angepaßt wird scrollArea->setWidget(imageLabel); // diese methode muß verwendet werden, die scrollarea als elternbehälter // im konstruktor des imageLabels anzugeben reicht nicht ! // QStatusBar anlegen statusBar = new QStatusBar(this); statusBar->setFont(QFont("Times", 12, QFont::Bold)); statusBar->setAutoFillBackground(true); //statusBar->showMessage("temporarily"); //Note that showMessage() is called to show temporary explanations of tool tip texts, //so passing a timeout of 0 is not sufficient to display a permanent message. // permanente meldunge erreicht man nur, wenn man ein eigenes label erzeugt und mit // addPermanentWidget in die statusbar aufnimmt. // label für permanente meldungen in der statuszeile permanentLabel = new QLabel(); statusBar->addPermanentWidget(permanentLabel, 1); permanentLabel->setText("für permanente meldungen"); // parameter 0 bedeutet, daß das label auf der rechten seite links vom anfasser plaziert wird // und somit zwei meldungen angezeigt werden, die temporäre und die permanente // parameter 1 bedeutet, daß das label auf der linken seite angezeigt wird und somit // die temporäre meldung nicht mehr angezeigt wird // farbe für QStatusBar QPalette statusPalette(statusBar->palette()); QColor grau(220,230,240, 255); // r,g,b,a statusPalette.setColor(QPalette::Background, grau); statusBar->setPalette(statusPalette); this->setStatusBar(statusBar); } void MainWindow::initMenuBar() { // QMenuBar (einrichten der menuzeile) menuBar = new QMenuBar(); menuBar->setObjectName(QString::fromUtf8("menuBar")); menuBar->setGeometry(QRect(0, 0, 300, 18)); this->setMenuBar(menuBar); // eine leere menubar wird nicht angezeigt // openmenu QMenu *fileMenu = new QMenu(); fileMenu = menuBar->addMenu(tr("&file")); // openAction QAction* openAction = new QAction("open Qt dialog", this); openAction->setShortcut(tr("Ctrl+O")); // setShortcut will eine QKeySequence, deswegen das makro tr fileMenu->addAction(openAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(openAction, SIGNAL(triggered()), this, SLOT(openQtDialog())); // winOpenAction QAction* winOpenAction = new QAction("open MS dialog", this); winOpenAction->setShortcut(tr("Ctrl+W")); fileMenu->addAction(winOpenAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(winOpenAction, SIGNAL(triggered()), this, SLOT(openWinDialog())); // exitAction QAction* closeAction = new QAction("exit", this); closeAction->setShortcut(tr("Ctrl+X")); fileMenu->addAction(closeAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(closeAction, SIGNAL(triggered()), this, SLOT(close())); // showmenu QMenu *showMenu = new QMenu(); showMenu = menuBar->addMenu(tr("&show")); // muß membervariable sein, weil wir im slot toggleAction darauf zugreifen müssen showAction = new QAction("hide statusbar", this); showAction->setShortcut(tr("Ctrl+T")); showMenu->addAction(showAction); // ohne addAction wird MenuItem nicht angezeigt //sender-empfänger-verbindung QObject::connect(showAction, SIGNAL(triggered()), this, SLOT(toggleAction())); } void MainWindow::initFileDialog() { fileDialog = new QFileDialog(this); // nur notwendig für den qt-filedialog QObject::connect(fileDialog, SIGNAL(fileSelected(const QString&)), this, SLOT(fileHandler(const QString&))); } // overriding void MainWindow::resizeEvent(QResizeEvent * event) { QMainWindow::resizeEvent(event); QSize size = this->size(); this->sizeChanged(size); } void MainWindow::sizeChanged(QSize& size) { int statusBarHeight = statusBar->size().height(); int menuBarHeight = menuBar->size().height(); if( statusBar->isHidden()) { scrollArea->setGeometry(QRect(border, border, size.width()- 2*border, size.height()- (2*border + menuBarHeight) )); // notwendig } else { scrollArea->setGeometry(QRect(border, border, size.width()- 2*border, size.height()-(2*border + menuBarHeight + statusBarHeight) )); // notwendig } } //slot void MainWindow::openQtDialog() { // bringt einen qt4 filedialog fileDialog->show(); } //slot void MainWindow::openWinDialog() { // getOpenFileName bringt den windowsfiledialog QString fileName = fileDialog->getOpenFileName(this); QImage* qImage = new QImage(fileName); imageLabel->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); permanentLabel->setText(fileName); } //slot void MainWindow::fileHandler(const QString& fileName) { QImage* qImage = new QImage(fileName); imageLabel->setPixmap(QPixmap::fromImage(*qImage, Qt::AutoColor)); permanentLabel->setText(fileName); } //slot void MainWindow::toggleAction() { if( statusBar->isHidden() ) { showAction->setText("hide statusbar"); statusBar->show(); } else { showAction->setText("show statusbar"); statusBar->hide(); } QSize size = this->size(); this->sizeChanged(size); } /* main.cpp */ #include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }