C++/Qt/Window — различия между версиями
Admin (обсуждение | вклад) м (1 версия: Импорт контента...) |
Admin (обсуждение | вклад) м (1 версия: Импорт контента...) |
(нет различий)
|
Текущая версия на 10:25, 25 мая 2010
Содержание
MdiWindow based editor
Foundations of Qt Development\Chapter04\mdi\documentwindow.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QCloseEvent>
#include <QMessageBox>
#include <QTextEdit>
#include "documentwindow.h"
DocumentWindow::DocumentWindow( QWidget *parent ) : QTextEdit( parent )
{
setAttribute( Qt::WA_DeleteOnClose );
setWindowTitle( tr("%1[*]" ).arg("unnamed") );
connect( document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)) );
}
void DocumentWindow::closeEvent( QCloseEvent *event )
{
if( isSafeToClose() )
event->accept();
else
event->ignore();
}
bool DocumentWindow::isSafeToClose()
{
if( document()->isModified() )
{
switch( QMessageBox::warning( this, tr("MDI"),
tr("The document has unsaved changes.\n"
"Do you want to save it before it is closed?"),
QMessageBox::Discard | QMessageBox::Cancel ) )
{
case QMessageBox::Cancel:
return false;
default:
return true;
}
}
return true;
}
Foundations of Qt Development\Chapter04\mdi\documentwindow.h
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef DOCUMENTWINDOW_H
#define DOCUMENTWINDOW_H
#include <QTextEdit>
class DocumentWindow : public QTextEdit
{
Q_OBJECT
public:
DocumentWindow( QWidget *parent = 0 );
protected:
void closeEvent( QCloseEvent *event );
private:
bool isSafeToClose();
};
#endif // DOCUMENTWINDOW_H
Foundations of Qt Development\Chapter04\mdi\main.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include "mdiwindow.h"
int main( int argc, char **argv )
{
QApplication app( argc, argv );
MdiWindow win;
win.show();
return app.exec();
}
Foundations of Qt Development\Chapter04\mdi\mdiwindow.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QCloseEvent>
#include <QMessageBox>
#include <QWorkspace>
#include <QSignalMapper>
#include "mdiwindow.h"
#include "documentwindow.h"
MdiWindow::MdiWindow( QWidget *parent ) : QMainWindow( parent )
{
setWindowTitle( tr( "MDI" ) );
workspace = new QWorkspace;
setCentralWidget( workspace );
connect( workspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(enableActions()));
mapper = new QSignalMapper( this );
connect( mapper, SIGNAL(mapped(QWidget*)), workspace, SLOT(setActiveWindow(QWidget*)) );
createActions();
createMenus();
createToolbars();
statusBar()->showMessage( tr("Done") );
enableActions();
}
void MdiWindow::closeEvent( QCloseEvent *event )
{
workspace->closeAllWindows();
if( !activeDocument() )
event->accept();
else
event->ignore();
}
void MdiWindow::fileNew()
{
DocumentWindow *document = new DocumentWindow;
workspace->addWindow( document );
connect( document, SIGNAL(copyAvailable(bool)), cutAction, SLOT(setEnabled(bool)) );
connect( document, SIGNAL(copyAvailable(bool)), copyAction, SLOT(setEnabled(bool)) );
document->show();
}
void MdiWindow::helpAbout()
{
QMessageBox::about( this, tr("About MDI"), tr("A multiple document interface application.") );
}
DocumentWindow *MdiWindow::activeDocument()
{
return qobject_cast<DocumentWindow*>(workspace->activeWindow());
}
void MdiWindow::enableActions()
{
bool hasDocuments = (activeDocument() != 0 );
closeAction->setEnabled( hasDocuments );
pasteAction->setEnabled( hasDocuments );
tileAction->setEnabled( hasDocuments );
cascadeAction->setEnabled( hasDocuments );
nextAction->setEnabled( hasDocuments );
previousAction->setEnabled( hasDocuments );
separatorAction->setVisible( hasDocuments );
bool hasSelection = hasDocuments && activeDocument()->textCursor().hasSelection();
cutAction->setEnabled( hasSelection );
copyAction->setEnabled( hasSelection );
}
void MdiWindow::createActions()
{
newAction = new QAction( QIcon(":/images/new.png"), tr("&New"), this );
newAction->setShortcut( tr("Ctrl+N") );
newAction->setStatusTip( tr("Create a new document") );
connect( newAction, SIGNAL(triggered()), this, SLOT(fileNew()) );
closeAction = new QAction( tr("&Close"), this );
closeAction->setShortcut( tr("Ctrl+W") );
closeAction->setStatusTip( tr("Close this document") );
connect( closeAction, SIGNAL(triggered()), workspace, SLOT(closeActiveWindow()) );
exitAction = new QAction( tr("E&xit"), this );
exitAction->setShortcut( tr("Ctrl+Q") );
exitAction->setStatusTip( tr("Quit the application") );
connect( exitAction, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()) );
cutAction = new QAction( QIcon(":/images/cut.png"), tr("Cu&t"), this );
cutAction->setShortcut( tr("Ctrl+X") );
cutAction->setStatusTip( tr("Cut") );
cutAction->setEnabled(false);
connect( cutAction, SIGNAL(triggered()), this, SLOT(editCut()) );
copyAction = new QAction( QIcon(":/images/copy.png"), tr("&Copy"), this );
copyAction->setShortcut( tr("Ctrl+C") );
copyAction->setStatusTip( tr("Copy") );
copyAction->setEnabled(false);
connect( copyAction, SIGNAL(triggered()), this, SLOT(editCopy()) );
pasteAction = new QAction( QIcon(":/images/paste.png"), tr("&Paste"), this );
pasteAction->setShortcut( tr("Ctrl+V") );
pasteAction->setStatusTip( tr("Paste") );
connect( pasteAction, SIGNAL(triggered()), this, SLOT(editPaste()) );
tileAction = new QAction( tr("&Tile"), this );
tileAction->setStatusTip( tr("Tile the windows") );
connect( tileAction, SIGNAL(triggered()), workspace, SLOT(tile()) );
cascadeAction = new QAction( tr("&Cascade"), this );
cascadeAction->setStatusTip( tr("Cascade the windows") );
connect( cascadeAction, SIGNAL(triggered()), workspace, SLOT(cascade()) );
nextAction = new QAction( tr("&Next window"), this );
nextAction->setStatusTip( tr("Move to the next window") );
connect( nextAction, SIGNAL(triggered()), workspace, SLOT(activateNextWindow()) );
previousAction = new QAction( tr("&Previous window"), this );
previousAction->setStatusTip( tr("Move to the previous window") );
connect( previousAction, SIGNAL(triggered()), workspace, SLOT(activatePreviousWindow()) );
separatorAction = new QAction( this );
separatorAction->setSeparator( true );
aboutAction = new QAction( tr("&About"), this );
aboutAction->setStatusTip( tr("About this application") );
connect( aboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()) );
aboutQtAction = new QAction( tr("About &Qt"), this );
aboutQtAction->setStatusTip( tr("About the Qt toolkit") );
connect( aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()) );
}
void MdiWindow::createMenus()
{
QMenu *menu;
menu = menuBar()->addMenu( tr("&File") );
menu->addAction( newAction );
menu->addAction( closeAction );
menu->addSeparator();
menu->addAction( exitAction );
menu = menuBar()->addMenu( tr("&Edit") );
menu->addAction( cutAction );
menu->addAction( copyAction );
menu->addAction( pasteAction );
windowMenu = menuBar()->addMenu( tr("&Window") );
connect( windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowList()) );
menu = menuBar()->addMenu( tr("&Help") );
menu->addAction( aboutAction );
menu->addAction( aboutQtAction );
}
void MdiWindow::createToolbars()
{
QToolBar *toolbar;
toolbar = addToolBar( tr("File") );
toolbar->addAction( newAction );
toolbar = addToolBar( tr("Edit") );
toolbar->addAction( cutAction );
toolbar->addAction( copyAction );
toolbar->addAction( pasteAction );
}
void MdiWindow::editCut()
{
activeDocument()->cut();
}
void MdiWindow::editCopy()
{
activeDocument()->copy();
}
void MdiWindow::editPaste()
{
activeDocument()->paste();
}
void MdiWindow::updateWindowList()
{
windowMenu->clear();
windowMenu->addAction( tileAction );
windowMenu->addAction( cascadeAction );
windowMenu->addSeparator();
windowMenu->addAction( nextAction );
windowMenu->addAction( previousAction );
windowMenu->addAction( separatorAction );
int i=1;
foreach( QWidget *w, workspace->windowList() )
{
QString text;
if( i<10 )
text = tr("&%1 %2").arg( i++ ).arg( w->windowTitle() );
else
text = w->windowTitle();
QAction *action = windowMenu->addAction( text );
action->setCheckable( true );
action->setChecked( w == activeDocument() );
connect( action, SIGNAL(triggered()), mapper, SLOT(map()) );
mapper->setMapping( action, w );
}
}
Foundations of Qt Development\Chapter04\mdi\mdiwindow.h
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MDIWINDOW_H
#define MDIWINDOW_H
#include <QMainWindow>
class QAction;
class QWorkspace;
class QSignalMapper;
class QMenu;
class DocumentWindow;
class MdiWindow : public QMainWindow
{
Q_OBJECT
public:
MdiWindow( QWidget *parent = 0 );
protected:
void closeEvent( QCloseEvent *event );
private slots:
void fileNew();
void editCut();
void editCopy();
void editPaste();
void helpAbout();
void enableActions();
void updateWindowList();
private:
void createActions();
void createMenus();
void createToolbars();
DocumentWindow *activeDocument();
QWorkspace *workspace;
QSignalMapper *mapper;
QAction *newAction;
QAction *closeAction;
QAction *exitAction;
QAction *cutAction;
QAction *copyAction;
QAction *pasteAction;
QAction *tileAction;
QAction *cascadeAction;
QAction *nextAction;
QAction *previousAction;
QAction *separatorAction;
QAction *aboutAction;
QAction *aboutQtAction;
QMenu *windowMenu;
};
#endif // MDIWINDOW_H
Qt based application window
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
class QPlainTextEdit;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void about();
void documentWasModified();
private:
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
bool maybeSave();
void loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
QPlainTextEdit *textEdit;
QString curFile;
QMenu *fileMenu;
QMenu *editMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *exitAct;
QAction *cutAct;
QAction *copyAct;
QAction *pasteAct;
QAction *aboutAct;
QAction *aboutQtAct;
};
#endif
#include <QtGui>
#include "mainwindow.h"
MainWindow::MainWindow()
{
textEdit = new QPlainTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (maybeSave()) {
writeSettings();
event->accept();
} else {
event->ignore();
}
}
void MainWindow::newFile()
{
if (maybeSave()) {
textEdit->clear();
setCurrentFile("");
}
}
void MainWindow::open()
{
if (maybeSave()) {
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
loadFile(fileName);
}
}
bool MainWindow::save()
{
if (curFile.isEmpty()) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this);
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About Application"),
tr("The <b>Application</b> example demonstrates how to "
"write modern GUI applications using Qt, with a menu bar, "
"toolbars, and a status bar."));
}
void MainWindow::documentWasModified()
{
setWindowModified(textEdit->document()->isModified());
}
void MainWindow::createActions()
{
newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("Save the document to disk"));
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("Save &As..."), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("Save the document under a new name"));
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcut(tr("Ctrl+Q"));
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("Cut the current selection"s contents to the "
"clipboard"));
connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut()));
copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
copyAct->setShortcuts(QKeySequence::Copy);
copyAct->setStatusTip(tr("Copy the current selection"s contents to the "
"clipboard"));
connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy()));
pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("Paste the clipboard"s contents into the current "
"selection"));
connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste()));
aboutAct = new QAction(tr("&About"), this);
aboutAct->setStatusTip(tr("Show the application"s About box"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAct = new QAction(tr("About &Qt"), this);
aboutQtAct->setStatusTip(tr("Show the Qt library"s About box"));
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, SIGNAL(copyAvailable(bool)),
cutAct, SLOT(setEnabled(bool)));
connect(textEdit, SIGNAL(copyAvailable(bool)),
copyAct, SLOT(setEnabled(bool)));
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::readSettings()
{
QSettings settings("Trolltech", "Application Example");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
resize(size);
move(pos);
}
void MainWindow::writeSettings()
{
QSettings settings("Trolltech", "Application Example");
settings.setValue("pos", pos());
settings.setValue("size", size());
}
bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("Application"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
textEdit->setPlainText(in.readAll());
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
bool MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
out << textEdit->toPlainText();
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
void MainWindow::setCurrentFile(const QString &fileName)
{
curFile = fileName;
textEdit->document()->setModified(false);
setWindowModified(false);
QString shownName;
if (curFile.isEmpty())
shownName = "untitled.txt";
else
shownName = strippedName(curFile);
setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Application")));
}
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(application);
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
Qt MDI window
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MDICHILD_H
#define MDICHILD_H
#include <QTextEdit>
class MdiChild : public QTextEdit
{
Q_OBJECT
public:
MdiChild();
void newFile();
bool loadFile(const QString &fileName);
bool save();
bool saveAs();
bool saveFile(const QString &fileName);
QString userFriendlyCurrentFile();
QString currentFile() { return curFile; }
protected:
void closeEvent(QCloseEvent *event);
private slots:
void documentWasModified();
private:
bool maybeSave();
void setCurrentFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
QString curFile;
bool isUntitled;
};
#endif
#include <QtGui>
#include "mdichild.h"
MdiChild::MdiChild()
{
setAttribute(Qt::WA_DeleteOnClose);
isUntitled = true;
}
void MdiChild::newFile()
{
static int sequenceNumber = 1;
isUntitled = true;
curFile = tr("document%1.txt").arg(sequenceNumber++);
setWindowTitle(curFile + "[*]");
connect(document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
}
bool MdiChild::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("MDI"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
setPlainText(in.readAll());
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
connect(document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
return true;
}
bool MdiChild::save()
{
if (isUntitled) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool MdiChild::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
curFile);
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
bool MdiChild::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("MDI"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
out << toPlainText();
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
return true;
}
QString MdiChild::userFriendlyCurrentFile()
{
return strippedName(curFile);
}
void MdiChild::closeEvent(QCloseEvent *event)
{
if (maybeSave()) {
event->accept();
} else {
event->ignore();
}
}
void MdiChild::documentWasModified()
{
setWindowModified(document()->isModified());
}
bool MdiChild::maybeSave()
{
if (document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("MDI"),
tr(""%1" has been modified.\n"
"Do you want to save your changes?")
.arg(userFriendlyCurrentFile()),
QMessageBox::Save | QMessageBox::Discard
| QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
void MdiChild::setCurrentFile(const QString &fileName)
{
curFile = QFileInfo(fileName).canonicalFilePath();
isUntitled = false;
document()->setModified(false);
setWindowModified(false);
setWindowTitle(userFriendlyCurrentFile() + "[*]");
}
QString MdiChild::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MdiChild;
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
class QMdiArea;
class QMdiSubWindow;
class QSignalMapper;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void newFile();
void open();
void save();
void saveAs();
void cut();
void copy();
void paste();
void about();
void updateMenus();
void updateWindowMenu();
MdiChild *createMdiChild();
void switchLayoutDirection();
void setActiveSubWindow(QWidget *window);
private:
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
MdiChild *activeMdiChild();
QMdiSubWindow *findMdiChild(const QString &fileName);
QMdiArea *mdiArea;
QSignalMapper *windowMapper;
QMenu *fileMenu;
QMenu *editMenu;
QMenu *windowMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *exitAct;
QAction *cutAct;
QAction *copyAct;
QAction *pasteAct;
QAction *closeAct;
QAction *closeAllAct;
QAction *tileAct;
QAction *cascadeAct;
QAction *nextAct;
QAction *previousAct;
QAction *separatorAct;
QAction *aboutAct;
QAction *aboutQtAct;
};
#endif
#include <QtGui>
#include "mainwindow.h"
#include "mdichild.h"
MainWindow::MainWindow()
{
mdiArea = new QMdiArea;
mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setCentralWidget(mdiArea);
connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)),
this, SLOT(updateMenus()));
windowMapper = new QSignalMapper(this);
connect(windowMapper, SIGNAL(mapped(QWidget *)),
this, SLOT(setActiveSubWindow(QWidget *)));
createActions();
createMenus();
createToolBars();
createStatusBar();
updateMenus();
readSettings();
setWindowTitle(tr("MDI"));
setUnifiedTitleAndToolBarOnMac(true);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
mdiArea->closeAllSubWindows();
if (activeMdiChild()) {
event->ignore();
} else {
writeSettings();
event->accept();
}
}
void MainWindow::newFile()
{
MdiChild *child = createMdiChild();
child->newFile();
child->show();
}
void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) {
QMdiSubWindow *existing = findMdiChild(fileName);
if (existing) {
mdiArea->setActiveSubWindow(existing);
return;
}
MdiChild *child = createMdiChild();
if (child->loadFile(fileName)) {
statusBar()->showMessage(tr("File loaded"), 2000);
child->show();
} else {
child->close();
}
}
}
void MainWindow::save()
{
if (activeMdiChild() && activeMdiChild()->save())
statusBar()->showMessage(tr("File saved"), 2000);
}
void MainWindow::saveAs()
{
if (activeMdiChild() && activeMdiChild()->saveAs())
statusBar()->showMessage(tr("File saved"), 2000);
}
void MainWindow::cut()
{
if (activeMdiChild())
activeMdiChild()->cut();
}
void MainWindow::copy()
{
if (activeMdiChild())
activeMdiChild()->copy();
}
void MainWindow::paste()
{
if (activeMdiChild())
activeMdiChild()->paste();
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About MDI"),
tr("The <b>MDI</b> example demonstrates how to write multiple "
"document interface applications using Qt."));
}
void MainWindow::updateMenus()
{
bool hasMdiChild = (activeMdiChild() != 0);
saveAct->setEnabled(hasMdiChild);
saveAsAct->setEnabled(hasMdiChild);
pasteAct->setEnabled(hasMdiChild);
closeAct->setEnabled(hasMdiChild);
closeAllAct->setEnabled(hasMdiChild);
tileAct->setEnabled(hasMdiChild);
cascadeAct->setEnabled(hasMdiChild);
nextAct->setEnabled(hasMdiChild);
previousAct->setEnabled(hasMdiChild);
separatorAct->setVisible(hasMdiChild);
bool hasSelection = (activeMdiChild() &&
activeMdiChild()->textCursor().hasSelection());
cutAct->setEnabled(hasSelection);
copyAct->setEnabled(hasSelection);
}
void MainWindow::updateWindowMenu()
{
windowMenu->clear();
windowMenu->addAction(closeAct);
windowMenu->addAction(closeAllAct);
windowMenu->addSeparator();
windowMenu->addAction(tileAct);
windowMenu->addAction(cascadeAct);
windowMenu->addSeparator();
windowMenu->addAction(nextAct);
windowMenu->addAction(previousAct);
windowMenu->addAction(separatorAct);
QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
separatorAct->setVisible(!windows.isEmpty());
for (int i = 0; i < windows.size(); ++i) {
MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget());
QString text;
if (i < 9) {
text = tr("&%1 %2").arg(i + 1)
.arg(child->userFriendlyCurrentFile());
} else {
text = tr("%1 %2").arg(i + 1)
.arg(child->userFriendlyCurrentFile());
}
QAction *action = windowMenu->addAction(text);
action->setCheckable(true);
action ->setChecked(child == activeMdiChild());
connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
windowMapper->setMapping(action, windows.at(i));
}
}
MdiChild *MainWindow::createMdiChild()
{
MdiChild *child = new MdiChild;
mdiArea->addSubWindow(child);
connect(child, SIGNAL(copyAvailable(bool)),
cutAct, SLOT(setEnabled(bool)));
connect(child, SIGNAL(copyAvailable(bool)),
copyAct, SLOT(setEnabled(bool)));
return child;
}
void MainWindow::createActions()
{
newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("Save the document to disk"));
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("Save &As..."), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("Save the document under a new name"));
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcut(tr("Ctrl+Q"));
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("Cut the current selection"s contents to the "
"clipboard"));
connect(cutAct, SIGNAL(triggered()), this, SLOT(cut()));
copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
copyAct->setShortcuts(QKeySequence::Copy);
copyAct->setStatusTip(tr("Copy the current selection"s contents to the "
"clipboard"));
connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));
pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("Paste the clipboard"s contents into the current "
"selection"));
connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste()));
closeAct = new QAction(tr("Cl&ose"), this);
closeAct->setShortcut(tr("Ctrl+F4"));
closeAct->setStatusTip(tr("Close the active window"));
connect(closeAct, SIGNAL(triggered()),
mdiArea, SLOT(closeActiveSubWindow()));
closeAllAct = new QAction(tr("Close &All"), this);
closeAllAct->setStatusTip(tr("Close all the windows"));
connect(closeAllAct, SIGNAL(triggered()),
mdiArea, SLOT(closeAllSubWindows()));
tileAct = new QAction(tr("&Tile"), this);
tileAct->setStatusTip(tr("Tile the windows"));
connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
cascadeAct = new QAction(tr("&Cascade"), this);
cascadeAct->setStatusTip(tr("Cascade the windows"));
connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));
nextAct = new QAction(tr("Ne&xt"), this);
nextAct->setShortcuts(QKeySequence::NextChild);
nextAct->setStatusTip(tr("Move the focus to the next window"));
connect(nextAct, SIGNAL(triggered()),
mdiArea, SLOT(activateNextSubWindow()));
previousAct = new QAction(tr("Pre&vious"), this);
previousAct->setShortcuts(QKeySequence::PreviousChild);
previousAct->setStatusTip(tr("Move the focus to the previous "
"window"));
connect(previousAct, SIGNAL(triggered()),
mdiArea, SLOT(activatePreviousSubWindow()));
separatorAct = new QAction(this);
separatorAct->setSeparator(true);
aboutAct = new QAction(tr("&About"), this);
aboutAct->setStatusTip(tr("Show the application"s About box"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAct = new QAction(tr("About &Qt"), this);
aboutQtAct->setStatusTip(tr("Show the Qt library"s About box"));
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
QAction *action = fileMenu->addAction(tr("Switch layout direction"));
connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection()));
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
windowMenu = menuBar()->addMenu(tr("&Window"));
updateWindowMenu();
connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::readSettings()
{
QSettings settings("Trolltech", "MDI Example");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
move(pos);
resize(size);
}
void MainWindow::writeSettings()
{
QSettings settings("Trolltech", "MDI Example");
settings.setValue("pos", pos());
settings.setValue("size", size());
}
MdiChild *MainWindow::activeMdiChild()
{
if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
return qobject_cast<MdiChild *>(activeSubWindow->widget());
return 0;
}
QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName)
{
QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
foreach (QMdiSubWindow *window, mdiArea->subWindowList()) {
MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget());
if (mdiChild->currentFile() == canonicalFilePath)
return window;
}
return 0;
}
void MainWindow::switchLayoutDirection()
{
if (layoutDirection() == Qt::LeftToRight)
qApp->setLayoutDirection(Qt::RightToLeft);
else
qApp->setLayoutDirection(Qt::LeftToRight);
}
void MainWindow::setActiveSubWindow(QWidget *window)
{
if (!window)
return;
mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
}
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(mdi);
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
Qt SDI window
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
class QAction;
class QMenu;
class QTextEdit;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
MainWindow(const QString &fileName);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void about();
void documentWasModified();
private:
void init();
void createActions();
void createMenus();
void createToolBars();
void createStatusBar();
void readSettings();
void writeSettings();
bool maybeSave();
void loadFile(const QString &fileName);
bool saveFile(const QString &fileName);
void setCurrentFile(const QString &fileName);
QString strippedName(const QString &fullFileName);
MainWindow *findMainWindow(const QString &fileName);
QTextEdit *textEdit;
QString curFile;
bool isUntitled;
QMenu *fileMenu;
QMenu *editMenu;
QMenu *helpMenu;
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAct;
QAction *openAct;
QAction *saveAct;
QAction *saveAsAct;
QAction *closeAct;
QAction *exitAct;
QAction *cutAct;
QAction *copyAct;
QAction *pasteAct;
QAction *aboutAct;
QAction *aboutQtAct;
};
#endif
#include <QtGui>
#include "mainwindow.h"
MainWindow::MainWindow()
{
init();
setCurrentFile("");
}
MainWindow::MainWindow(const QString &fileName)
{
init();
loadFile(fileName);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if (maybeSave()) {
writeSettings();
event->accept();
} else {
event->ignore();
}
}
void MainWindow::newFile()
{
MainWindow *other = new MainWindow;
other->move(x() + 40, y() + 40);
other->show();
}
void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty()) {
MainWindow *existing = findMainWindow(fileName);
if (existing) {
existing->show();
existing->raise();
existing->activateWindow();
return;
}
if (isUntitled && textEdit->document()->isEmpty()
&& !isWindowModified()) {
loadFile(fileName);
} else {
MainWindow *other = new MainWindow(fileName);
if (other->isUntitled) {
delete other;
return;
}
other->move(x() + 40, y() + 40);
other->show();
}
}
}
bool MainWindow::save()
{
if (isUntitled) {
return saveAs();
} else {
return saveFile(curFile);
}
}
bool MainWindow::saveAs()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
curFile);
if (fileName.isEmpty())
return false;
return saveFile(fileName);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About SDI"),
tr("The <b>SDI</b> example demonstrates how to write single "
"document interface applications using Qt."));
}
void MainWindow::documentWasModified()
{
setWindowModified(true);
}
void MainWindow::init()
{
setAttribute(Qt::WA_DeleteOnClose);
isUntitled = true;
textEdit = new QTextEdit;
setCentralWidget(textEdit);
createActions();
createMenus();
createToolBars();
createStatusBar();
readSettings();
connect(textEdit->document(), SIGNAL(contentsChanged()),
this, SLOT(documentWasModified()));
setUnifiedTitleAndToolBarOnMac(true);
}
void MainWindow::createActions()
{
newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
newAct->setShortcuts(QKeySequence::New);
newAct->setStatusTip(tr("Create a new file"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
saveAct->setShortcuts(QKeySequence::Save);
saveAct->setStatusTip(tr("Save the document to disk"));
connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr("Save &As..."), this);
saveAsAct->setShortcuts(QKeySequence::SaveAs);
saveAsAct->setStatusTip(tr("Save the document under a new name"));
connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
closeAct = new QAction(tr("&Close"), this);
closeAct->setShortcut(tr("Ctrl+W"));
closeAct->setStatusTip(tr("Close this window"));
connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
exitAct = new QAction(tr("E&xit"), this);
exitAct->setShortcut(tr("Ctrl+Q"));
exitAct->setStatusTip(tr("Exit the application"));
connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
cutAct->setShortcuts(QKeySequence::Cut);
cutAct->setStatusTip(tr("Cut the current selection"s contents to the "
"clipboard"));
connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut()));
copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
copyAct->setShortcuts(QKeySequence::Copy);
copyAct->setStatusTip(tr("Copy the current selection"s contents to the "
"clipboard"));
connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy()));
pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
pasteAct->setShortcuts(QKeySequence::Paste);
pasteAct->setStatusTip(tr("Paste the clipboard"s contents into the current "
"selection"));
connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste()));
aboutAct = new QAction(tr("&About"), this);
aboutAct->setStatusTip(tr("Show the application"s About box"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAct = new QAction(tr("About &Qt"), this);
aboutQtAct->setStatusTip(tr("Show the Qt library"s About box"));
connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
cutAct->setEnabled(false);
copyAct->setEnabled(false);
connect(textEdit, SIGNAL(copyAvailable(bool)),
cutAct, SLOT(setEnabled(bool)));
connect(textEdit, SIGNAL(copyAvailable(bool)),
copyAct, SLOT(setEnabled(bool)));
}
//! [implicit tr context]
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
//! [implicit tr context]
fileMenu->addAction(newAct);
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(closeAct);
fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr("&Edit"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAct);
helpMenu->addAction(aboutQtAct);
}
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
fileToolBar->addAction(openAct);
fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
}
void MainWindow::readSettings()
{
QSettings settings("Trolltech", "SDI Example");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(400, 400)).toSize();
move(pos);
resize(size);
}
void MainWindow::writeSettings()
{
QSettings settings("Trolltech", "SDI Example");
settings.setValue("pos", pos());
settings.setValue("size", size());
}
bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("SDI"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard
| QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
return false;
}
return true;
}
void MainWindow::loadFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("SDI"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
textEdit->setPlainText(in.readAll());
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
statusBar()->showMessage(tr("File loaded"), 2000);
}
bool MainWindow::saveFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("SDI"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return false;
}
QTextStream out(&file);
QApplication::setOverrideCursor(Qt::WaitCursor);
out << textEdit->toPlainText();
QApplication::restoreOverrideCursor();
setCurrentFile(fileName);
statusBar()->showMessage(tr("File saved"), 2000);
return true;
}
void MainWindow::setCurrentFile(const QString &fileName)
{
static int sequenceNumber = 1;
isUntitled = fileName.isEmpty();
if (isUntitled) {
curFile = tr("document%1.txt").arg(sequenceNumber++);
} else {
curFile = QFileInfo(fileName).canonicalFilePath();
}
textEdit->document()->setModified(false);
setWindowModified(false);
setWindowTitle(tr("%1[*] - %2").arg(strippedName(curFile))
.arg(tr("SDI")));
}
QString MainWindow::strippedName(const QString &fullFileName)
{
return QFileInfo(fullFileName).fileName();
}
MainWindow *MainWindow::findMainWindow(const QString &fileName)
{
QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
foreach (QWidget *widget, qApp->topLevelWidgets()) {
MainWindow *mainWin = qobject_cast<MainWindow *>(widget);
if (mainWin && mainWin->curFile == canonicalFilePath)
return mainWin;
}
return 0;
}
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(sdi);
QApplication app(argc, argv);
MainWindow *mainWin = new MainWindow;
mainWin->show();
return app.exec();
}
SdiWindow based text editor
Foundations of Qt Development\Chapter04\dock\infowidget.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "infowidget.h"
InfoWidget::InfoWidget( QWidget *parent ) : QLabel( parent )
{
setAlignment( Qt::AlignCenter );
setWordWrap( true );
setText( tr("Ready") );
}
void InfoWidget::documentChanged( int position, int charsRemoved, int charsAdded )
{
QString text;
if( charsRemoved )
text = tr("%1 removed").arg( charsRemoved );
if( charsRemoved && charsAdded )
text += tr(", ");
if( charsAdded )
text += tr("%1 added").arg( charsAdded );
setText( text );
}
Foundations of Qt Development\Chapter04\dock\infowidget.h
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef INFOWIDGET_H
#define INFOWIDGET_H
#include <QLabel>
class InfoWidget : public QLabel
{
Q_OBJECT
public:
InfoWidget( QWidget *parent=0 );
public slots:
void documentChanged( int position, int charsRemoved, int charsAdded );
};
#endif // INFOWIDGET_H
Foundations of Qt Development\Chapter04\dock\main.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include "sdiwindow.h"
int main( int argc, char **argv )
{
QApplication app( argc, argv );
(new SdiWindow)->show();
return app.exec();
}
Foundations of Qt Development\Chapter04\dock\sdiwindow.cpp
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <QApplication>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QCloseEvent>
#include <QMessageBox>
#include <QTextEdit>
#include <QDockWidget>
#include "infowidget.h"
#include "sdiwindow.h"
SdiWindow::SdiWindow( QWidget *parent ) : QMainWindow( parent )
{
setAttribute( Qt::WA_DeleteOnClose );
setWindowTitle( tr("%1[*] - %2" ).arg(tr("unnamed")).arg(tr("SDI")) );
docWidget = new QTextEdit( this );
setCentralWidget( docWidget );
connect( docWidget->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)) );
createDocks();
createActions();
createMenus();
createToolbars();
statusBar()->showMessage( tr("Done") );
}
void SdiWindow::createDocks()
{
dock = new QDockWidget( tr("Information"), this );
InfoWidget *info = new InfoWidget( dock );
dock->setWidget( info );
addDockWidget( Qt::LeftDockWidgetArea, dock );
connect( docWidget->document(), SIGNAL(contentsChange(int, int, int)), info, SLOT(documentChanged(int, int, int)) );
}
void SdiWindow::closeEvent( QCloseEvent *event )
{
if( isSafeToClose() )
event->accept();
else
event->ignore();
}
bool SdiWindow::isSafeToClose()
{
if( isWindowModified() )
{
switch( QMessageBox::warning( this, tr("SDI"),
tr("The document has unsaved changes.\n"
"Do you want to save it before it is closed?"),
QMessageBox::Discard | QMessageBox::Cancel ) )
{
case QMessageBox::Cancel:
return false;
default:
return true;
}
}
return true;
}
void SdiWindow::fileNew()
{
(new SdiWindow())->show();
}
void SdiWindow::helpAbout()
{
QMessageBox::about( this, tr("About SDI"), tr("A single document interface application.") );
}
void SdiWindow::createActions()
{
newAction = new QAction( QIcon(":/images/new.png"), tr("&New"), this );
newAction->setShortcut( tr("Ctrl+N") );
newAction->setStatusTip( tr("Create a new document") );
connect( newAction, SIGNAL(triggered()), this, SLOT(fileNew()) );
closeAction = new QAction( tr("&Close"), this );
closeAction->setShortcut( tr("Ctrl+W") );
closeAction->setStatusTip( tr("Close this document") );
connect( closeAction, SIGNAL(triggered()), this, SLOT(close()) );
exitAction = new QAction( tr("E&xit"), this );
exitAction->setShortcut( tr("Ctrl+Q") );
exitAction->setStatusTip( tr("Quit the application") );
connect( exitAction, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()) );
cutAction = new QAction( QIcon(":/images/cut.png"), tr("Cu&t"), this );
cutAction->setShortcut( tr("Ctrl+X") );
cutAction->setStatusTip( tr("Cut") );
cutAction->setEnabled(false);
connect( docWidget, SIGNAL(copyAvailable(bool)), cutAction, SLOT(setEnabled(bool)) );
connect( cutAction, SIGNAL(triggered()), docWidget, SLOT(cut()) );
copyAction = new QAction( QIcon(":/images/copy.png"), tr("&Copy"), this );
copyAction->setShortcut( tr("Ctrl+C") );
copyAction->setStatusTip( tr("Copy") );
copyAction->setEnabled(false);
connect( docWidget, SIGNAL(copyAvailable(bool)), copyAction, SLOT(setEnabled(bool)) );
connect( copyAction, SIGNAL(triggered()), docWidget, SLOT(copy()) );
pasteAction = new QAction( QIcon(":/images/paste.png"), tr("&Paste"), this );
pasteAction->setShortcut( tr("Ctrl+V") );
pasteAction->setStatusTip( tr("Paste") );
connect( pasteAction, SIGNAL(triggered()), docWidget, SLOT(paste()) );
aboutAction = new QAction( tr("&About"), this );
aboutAction->setStatusTip( tr("About this application") );
connect( aboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()) );
aboutQtAction = new QAction( tr("About &Qt"), this );
aboutQtAction->setStatusTip( tr("About the Qt toolkit") );
connect( aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()) );
}
void SdiWindow::createMenus()
{
QMenu *menu;
menu = menuBar()->addMenu( tr("&File") );
menu->addAction( newAction );
menu->addAction( closeAction );
menu->addSeparator();
menu->addAction( exitAction );
menu = menuBar()->addMenu( tr("&Edit") );
menu->addAction( cutAction );
menu->addAction( copyAction );
menu->addAction( pasteAction );
menu = menuBar()->addMenu( tr("&View") );
menu->addAction( dock->toggleViewAction() );
menu = menuBar()->addMenu( tr("&Help") );
menu->addAction( aboutAction );
menu->addAction( aboutQtAction );
}
void SdiWindow::createToolbars()
{
QToolBar *toolbar;
toolbar = addToolBar( tr("File") );
toolbar->addAction( newAction );
toolbar = addToolBar( tr("Edit") );
toolbar->addAction( cutAction );
toolbar->addAction( copyAction );
toolbar->addAction( pasteAction );
}
Foundations of Qt Development\Chapter04\dock\sdiwindow.h
/*
* Copyright (c) 2006-2007, Johan Thelin
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of APress nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef SDIWINDOW_H
#define SDIWINDOW_H
#include <QMainWindow>
class QAction;
class QTextEdit;
class QDockWidget;
class SdiWindow : public QMainWindow
{
Q_OBJECT
public:
SdiWindow( QWidget *parent = 0 );
protected:
void closeEvent( QCloseEvent *event );
private slots:
void fileNew();
void helpAbout();
private:
void createDocks();
void createActions();
void createMenus();
void createToolbars();
bool isSafeToClose();
QTextEdit *docWidget;
QAction *newAction;
QAction *closeAction;
QAction *exitAction;
QAction *cutAction;
QAction *copyAction;
QAction *pasteAction;
QAction *aboutAction;
QAction *aboutQtAction;
QDockWidget *dock;
};
#endif // SDIWINDOW_H
Top level window
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//! [create, resize and show]
QWidget *window = new QWidget();
window->resize(320, 240);
window->show();
//! [create, resize and show]
window->setWindowTitle(tr("Top-level widget"));
return app.exec();
}
Window style flags
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef CONTROLLERWINDOW_H
#define CONTROLLERWINDOW_H
#include <QWidget>
#include "previewwindow.h"
QT_BEGIN_NAMESPACE
class QCheckBox;
class QGroupBox;
class QLabel;
class QPushButton;
class QRadioButton;
QT_END_NAMESPACE
class ControllerWindow : public QWidget
{
Q_OBJECT
public:
ControllerWindow();
private slots:
void updatePreview();
private:
void createTypeGroupBox();
void createHintsGroupBox();
QCheckBox *createCheckBox(const QString &text);
QRadioButton *createRadioButton(const QString &text);
PreviewWindow *previewWindow;
QGroupBox *typeGroupBox;
QGroupBox *hintsGroupBox;
QPushButton *quitButton;
QRadioButton *windowRadioButton;
QRadioButton *dialogRadioButton;
QRadioButton *sheetRadioButton;
QRadioButton *drawerRadioButton;
QRadioButton *popupRadioButton;
QRadioButton *toolRadioButton;
QRadioButton *toolTipRadioButton;
QRadioButton *splashScreenRadioButton;
QCheckBox *msWindowsFixedSizeDialogCheckBox;
QCheckBox *x11BypassWindowManagerCheckBox;
QCheckBox *framelessWindowCheckBox;
QCheckBox *windowTitleCheckBox;
QCheckBox *windowSystemMenuCheckBox;
QCheckBox *windowMinimizeButtonCheckBox;
QCheckBox *windowMaximizeButtonCheckBox;
QCheckBox *windowCloseButtonCheckBox;
QCheckBox *windowContextHelpButtonCheckBox;
QCheckBox *windowShadeButtonCheckBox;
QCheckBox *windowStaysOnTopCheckBox;
QCheckBox *windowStaysOnBottomCheckBox;
QCheckBox *customizeWindowHintCheckBox;
};
#endif
#include <QtGui>
#include "controllerwindow.h"
ControllerWindow::ControllerWindow()
{
previewWindow = new PreviewWindow(this);
createTypeGroupBox();
createHintsGroupBox();
quitButton = new QPushButton(tr("&Quit"));
connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QHBoxLayout *bottomLayout = new QHBoxLayout;
bottomLayout->addStretch();
bottomLayout->addWidget(quitButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(typeGroupBox);
mainLayout->addWidget(hintsGroupBox);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
setWindowTitle(tr("Window Flags"));
updatePreview();
}
void ControllerWindow::updatePreview()
{
Qt::WindowFlags flags = 0;
if (windowRadioButton->isChecked()) {
flags = Qt::Window;
} else if (dialogRadioButton->isChecked()) {
flags = Qt::Dialog;
} else if (sheetRadioButton->isChecked()) {
flags = Qt::Sheet;
} else if (drawerRadioButton->isChecked()) {
flags = Qt::Drawer;
} else if (popupRadioButton->isChecked()) {
flags = Qt::Popup;
} else if (toolRadioButton->isChecked()) {
flags = Qt::Tool;
} else if (toolTipRadioButton->isChecked()) {
flags = Qt::ToolTip;
} else if (splashScreenRadioButton->isChecked()) {
flags = Qt::SplashScreen;
}
if (msWindowsFixedSizeDialogCheckBox->isChecked())
flags |= Qt::MSWindowsFixedSizeDialogHint;
if (x11BypassWindowManagerCheckBox->isChecked())
flags |= Qt::X11BypassWindowManagerHint;
if (framelessWindowCheckBox->isChecked())
flags |= Qt::FramelessWindowHint;
if (windowTitleCheckBox->isChecked())
flags |= Qt::WindowTitleHint;
if (windowSystemMenuCheckBox->isChecked())
flags |= Qt::WindowSystemMenuHint;
if (windowMinimizeButtonCheckBox->isChecked())
flags |= Qt::WindowMinimizeButtonHint;
if (windowMaximizeButtonCheckBox->isChecked())
flags |= Qt::WindowMaximizeButtonHint;
if (windowCloseButtonCheckBox->isChecked())
flags |= Qt::WindowCloseButtonHint;
if (windowContextHelpButtonCheckBox->isChecked())
flags |= Qt::WindowContextHelpButtonHint;
if (windowShadeButtonCheckBox->isChecked())
flags |= Qt::WindowShadeButtonHint;
if (windowStaysOnTopCheckBox->isChecked())
flags |= Qt::WindowStaysOnTopHint;
if (windowStaysOnBottomCheckBox->isChecked())
flags |= Qt::WindowStaysOnBottomHint;
if (customizeWindowHintCheckBox->isChecked())
flags |= Qt::CustomizeWindowHint;
previewWindow->setWindowFlags(flags);
QPoint pos = previewWindow->pos();
if (pos.x() < 0)
pos.setX(0);
if (pos.y() < 0)
pos.setY(0);
previewWindow->move(pos);
previewWindow->show();
}
void ControllerWindow::createTypeGroupBox()
{
typeGroupBox = new QGroupBox(tr("Type"));
windowRadioButton = createRadioButton(tr("Window"));
dialogRadioButton = createRadioButton(tr("Dialog"));
sheetRadioButton = createRadioButton(tr("Sheet"));
drawerRadioButton = createRadioButton(tr("Drawer"));
popupRadioButton = createRadioButton(tr("Popup"));
toolRadioButton = createRadioButton(tr("Tool"));
toolTipRadioButton = createRadioButton(tr("Tooltip"));
splashScreenRadioButton = createRadioButton(tr("Splash screen"));
windowRadioButton->setChecked(true);
QGridLayout *layout = new QGridLayout;
layout->addWidget(windowRadioButton, 0, 0);
layout->addWidget(dialogRadioButton, 1, 0);
layout->addWidget(sheetRadioButton, 2, 0);
layout->addWidget(drawerRadioButton, 3, 0);
layout->addWidget(popupRadioButton, 0, 1);
layout->addWidget(toolRadioButton, 1, 1);
layout->addWidget(toolTipRadioButton, 2, 1);
layout->addWidget(splashScreenRadioButton, 3, 1);
typeGroupBox->setLayout(layout);
}
void ControllerWindow::createHintsGroupBox()
{
hintsGroupBox = new QGroupBox(tr("Hints"));
msWindowsFixedSizeDialogCheckBox =
createCheckBox(tr("MS Windows fixed size dialog"));
x11BypassWindowManagerCheckBox =
createCheckBox(tr("X11 bypass window manager"));
framelessWindowCheckBox = createCheckBox(tr("Frameless window"));
windowTitleCheckBox = createCheckBox(tr("Window title"));
windowSystemMenuCheckBox = createCheckBox(tr("Window system menu"));
windowMinimizeButtonCheckBox = createCheckBox(tr("Window minimize button"));
windowMaximizeButtonCheckBox = createCheckBox(tr("Window maximize button"));
windowCloseButtonCheckBox = createCheckBox(tr("Window close button"));
windowContextHelpButtonCheckBox =
createCheckBox(tr("Window context help button"));
windowShadeButtonCheckBox = createCheckBox(tr("Window shade button"));
windowStaysOnTopCheckBox = createCheckBox(tr("Window stays on top"));
windowStaysOnBottomCheckBox = createCheckBox(tr("Window stays on bottom"));
customizeWindowHintCheckBox= createCheckBox(tr("Customize window"));
QGridLayout *layout = new QGridLayout;
layout->addWidget(msWindowsFixedSizeDialogCheckBox, 0, 0);
layout->addWidget(x11BypassWindowManagerCheckBox, 1, 0);
layout->addWidget(framelessWindowCheckBox, 2, 0);
layout->addWidget(windowTitleCheckBox, 3, 0);
layout->addWidget(windowSystemMenuCheckBox, 4, 0);
layout->addWidget(windowMinimizeButtonCheckBox, 0, 1);
layout->addWidget(windowMaximizeButtonCheckBox, 1, 1);
layout->addWidget(windowCloseButtonCheckBox, 2, 1);
layout->addWidget(windowContextHelpButtonCheckBox, 3, 1);
layout->addWidget(windowShadeButtonCheckBox, 4, 1);
layout->addWidget(windowStaysOnTopCheckBox, 5, 1);
layout->addWidget(windowStaysOnBottomCheckBox, 6, 1);
layout->addWidget(customizeWindowHintCheckBox, 5, 0);
hintsGroupBox->setLayout(layout);
}
QCheckBox *ControllerWindow::createCheckBox(const QString &text)
{
QCheckBox *checkBox = new QCheckBox(text);
connect(checkBox, SIGNAL(clicked()), this, SLOT(updatePreview()));
return checkBox;
}
QRadioButton *ControllerWindow::createRadioButton(const QString &text)
{
QRadioButton *button = new QRadioButton(text);
connect(button, SIGNAL(clicked()), this, SLOT(updatePreview()));
return button;
}
#ifndef PREVIEWWINDOW_H
#define PREVIEWWINDOW_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QPushButton;
class QTextEdit;
QT_END_NAMESPACE
class PreviewWindow : public QWidget
{
Q_OBJECT
public:
PreviewWindow(QWidget *parent = 0);
void setWindowFlags(Qt::WindowFlags flags);
private:
QTextEdit *textEdit;
QPushButton *closeButton;
};
#endif
#include <QtGui>
#include "previewwindow.h"
PreviewWindow::PreviewWindow(QWidget *parent)
: QWidget(parent)
{
textEdit = new QTextEdit;
textEdit->setReadOnly(true);
textEdit->setLineWrapMode(QTextEdit::NoWrap);
closeButton = new QPushButton(tr("&Close"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(closeButton);
setLayout(layout);
setWindowTitle(tr("Preview"));
}
void PreviewWindow::setWindowFlags(Qt::WindowFlags flags)
{
QWidget::setWindowFlags(flags);
QString text;
Qt::WindowFlags type = (flags & Qt::WindowType_Mask);
if (type == Qt::Window) {
text = "Qt::Window";
} else if (type == Qt::Dialog) {
text = "Qt::Dialog";
} else if (type == Qt::Sheet) {
text = "Qt::Sheet";
} else if (type == Qt::Drawer) {
text = "Qt::Drawer";
} else if (type == Qt::Popup) {
text = "Qt::Popup";
} else if (type == Qt::Tool) {
text = "Qt::Tool";
} else if (type == Qt::ToolTip) {
text = "Qt::ToolTip";
} else if (type == Qt::SplashScreen) {
text = "Qt::SplashScreen";
}
if (flags & Qt::MSWindowsFixedSizeDialogHint)
text += "\n| Qt::MSWindowsFixedSizeDialogHint";
if (flags & Qt::X11BypassWindowManagerHint)
text += "\n| Qt::X11BypassWindowManagerHint";
if (flags & Qt::FramelessWindowHint)
text += "\n| Qt::FramelessWindowHint";
if (flags & Qt::WindowTitleHint)
text += "\n| Qt::WindowTitleHint";
if (flags & Qt::WindowSystemMenuHint)
text += "\n| Qt::WindowSystemMenuHint";
if (flags & Qt::WindowMinimizeButtonHint)
text += "\n| Qt::WindowMinimizeButtonHint";
if (flags & Qt::WindowMaximizeButtonHint)
text += "\n| Qt::WindowMaximizeButtonHint";
if (flags & Qt::WindowCloseButtonHint)
text += "\n| Qt::WindowCloseButtonHint";
if (flags & Qt::WindowContextHelpButtonHint)
text += "\n| Qt::WindowContextHelpButtonHint";
if (flags & Qt::WindowShadeButtonHint)
text += "\n| Qt::WindowShadeButtonHint";
if (flags & Qt::WindowStaysOnTopHint)
text += "\n| Qt::WindowStaysOnTopHint";
if (flags & Qt::CustomizeWindowHint)
text += "\n| Qt::CustomizeWindowHint";
textEdit->setPlainText(text);
}
#include <QApplication>
#include "controllerwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ControllerWindow controller;
controller.show();
return app.exec();
}