Название: Qt 4.2.2 Как скрестить MDI с Graphics View framework
Отправлено: Kuzemko от Февраль 11, 2007, 21:06
Для нужд проекта необходимо создать Graphics View framework MDI-редактор. Нашел пример текстового редактора в книге C++ GUI Programming with Qt 4 (глава 6), решил переделать. В результате переделки возникли глюки: когда закрываю активное окно, оно с экрана исчезает, но в меню Окна остается. У меня такое подозрение что я не правильно реализовал класс Editor. Привожу текст программы: mainwindow.cpp #include <QtGui> #include <QtDebug> #include "symboleditor.h" #include "mainwindow.h" MainWindow::MainWindow() { symbolEditorWorkspace = new QWorkspace ( this ); setCentralWidget ( symbolEditorWorkspace ); connect ( symbolEditorWorkspace, SIGNAL ( windowActivated ( QWidget * ) ), this, SLOT ( updateSymbolEditorMenus() ) ); createSymbolEditorActions(); createSymbolEditorMenus(); createSymbolEditorToolBars(); createSymbolEditorStatusBar(); setWindowTitle ( tr ( "SymbolEditor Редактор символов УГО" ) ); setWindowIcon ( QPixmap ( ":/images/icon.png" ) ); } void MainWindow::newFile() { qDebug("Run MainWindow::newFile"); SymbolEditor *symbolEditor = createSymbolEditor(); symbolEditor->newSymbolFile(); symbolEditor->show(); } void MainWindow::openFile ( const QString &fileName ) { SymbolEditor *symbolEditor = createSymbolEditor(); if ( symbolEditor->openSymbolFile ( fileName ) ) { symbolEditor->show(); } else { symbolEditor->close(); } } void MainWindow::closeEvent ( QCloseEvent *closeEvent ) { symbolEditorWorkspace->closeAllWindows(); if ( activeSymbolEditor() ) { closeEvent->ignore(); } else { closeEvent->accept(); } } void MainWindow::open() { SymbolEditor *symbolEditor = createSymbolEditor(); if ( symbolEditor->openSymbol() ) { symbolEditor->show(); } else { symbolEditor->close(); } } void MainWindow::save() { if ( activeSymbolEditor() ) activeSymbolEditor()->saveSymbol(); } void MainWindow::saveAs() { if ( activeSymbolEditor() ) activeSymbolEditor()->saveSymbolAs(); } void MainWindow::cut() { if ( activeSymbolEditor() ) activeSymbolEditor()->cutSymbol(); } void MainWindow::copy() { if ( activeSymbolEditor() ) activeSymbolEditor()->copySymbol(); ; } void MainWindow::paste() { if ( activeSymbolEditor() ) activeSymbolEditor()->pasteSymbol(); ; } void MainWindow::about() { QMessageBox::about ( this, tr ( "Про SymbolEditor - Редактор символов УГО" ), tr ( "<h2>SymbolEditor 0.0.1</h2>" "<p>Copyright © 2007 Software Inc." "<p>Редактор символов УГО - часть проекта KEDA" "<p>Автор: Куземко Александр" ) ); } void MainWindow::updateSymbolEditorMenus() { bool hasSymbolEditor = ( activeSymbolEditor() != 0 ); bool hasSymbolSelection = activeSymbolEditor() && activeSymbolEditor()->isSelected(); saveSymbolAction->setEnabled ( hasSymbolEditor ); saveSymbolAsAction->setEnabled ( hasSymbolEditor ); pasteSymbolAction->setEnabled ( hasSymbolEditor ); cutSymbolAction->setEnabled ( hasSymbolSelection ); copySymbolAction->setEnabled ( hasSymbolSelection ); closeAction->setEnabled ( hasSymbolEditor ); closeAllAction->setEnabled ( hasSymbolEditor ); tileAction->setEnabled ( hasSymbolEditor ); cascadeAction->setEnabled ( hasSymbolEditor ); nextAction->setEnabled ( hasSymbolEditor ); previousAction->setEnabled ( hasSymbolEditor ); separatorAction->setVisible ( hasSymbolEditor ); if ( activeSymbolEditor() ) activeSymbolEditor()->symbolWindowMenuAction()->setChecked ( true ); } void MainWindow::createSymbolEditorActions() { newSymbolAction = new QAction ( QIcon ( ":/images/new.png" ), tr ( "Новый" ), this ); newSymbolAction->setShortcut ( tr ( "Ctrl+N" ) ); newSymbolAction->setStatusTip ( tr ( "Создать новый файл символа УГО" ) ); connect ( newSymbolAction, SIGNAL ( triggered() ), this, SLOT ( newFile() ) ); openSymbolAction = new QAction ( QIcon ( ":/images/open.png" ), tr ( "Открыть..." ), this ); openSymbolAction->setShortcut ( tr ( "Ctrl+O" ) ); openSymbolAction->setStatusTip ( tr ( "Открыть существующий файл символа УГО" ) ); connect ( openSymbolAction, SIGNAL ( triggered() ), this, SLOT ( open() ) ); saveSymbolAction = new QAction ( QIcon ( ":/images/save.png" ), tr ( "Сохранить" ), this ); saveSymbolAction->setShortcut ( tr ( "Ctrl+S" ) ); saveSymbolAction->setStatusTip ( tr ( "Сохранить файл символа УГО на диск" ) ); connect ( saveSymbolAction, SIGNAL ( triggered() ), this, SLOT ( save() ) ); saveSymbolAsAction = new QAction ( tr ( "Сохранить как..." ), this ); saveSymbolAsAction->setStatusTip ( tr ( "Сохранить файл символа УГО под новым именем" ) ); connect ( saveSymbolAsAction, SIGNAL ( triggered() ), this, SLOT ( saveAs() ) ); exitAction = new QAction ( tr ( "Выйти" ), this ); exitAction->setShortcut ( tr ( "Ctrl+Q" ) ); exitAction->setStatusTip ( tr ( "Выйти из приложения" ) ); connect ( exitAction, SIGNAL ( triggered() ), this, SLOT ( close() ) ); addNewSymbolText = new QAction ( tr ( "Добавить надпись" ), this ); connect ( addNewSymbolText, SIGNAL ( triggered() ), this, SLOT ( addText() ) ); cutSymbolAction = new QAction ( QIcon ( ":/images/cut.png" ), tr ( "Cu&t" ), this ); cutSymbolAction->setShortcut ( tr ( "Ctrl+X" ) ); cutSymbolAction->setStatusTip ( tr ( "Вырезать в буфер обмена" ) ); connect ( cutSymbolAction, SIGNAL ( triggered() ), this, SLOT ( cut() ) ); copySymbolAction = new QAction ( QIcon ( ":/images/copy.png" ), tr ( "&Copy" ), this ); copySymbolAction->setShortcut ( tr ( "Ctrl+C" ) ); copySymbolAction->setStatusTip ( tr ( "Скопировать в буфер обмена" ) ); connect ( copySymbolAction, SIGNAL ( triggered() ), this, SLOT ( copy() ) ); pasteSymbolAction = new QAction ( QIcon ( ":/images/paste.png" ), tr ( "&Paste" ), this ); pasteSymbolAction->setShortcut ( tr ( "Ctrl+V" ) ); pasteSymbolAction->setStatusTip ( tr ( "Вставить из буфера обмена" ) ); connect ( pasteSymbolAction, SIGNAL ( triggered() ), this, SLOT ( paste() ) ); closeAction = new QAction ( tr ( "Закрыть" ), this ); closeAction->setShortcut ( tr ( "Ctrl+F4" ) ); closeAction->setStatusTip ( tr ( "Закрыть активное окно" ) ); connect ( closeAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( closeActiveWindow() ) ); closeAllAction = new QAction ( tr ( "Закрыть все" ), this ); closeAllAction->setStatusTip ( tr ( "Закрыть все окна" ) ); connect ( closeAllAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( closeAllWindows() ) ); tileAction = new QAction ( tr ( "Расположить черепицей" ), this ); tileAction->setStatusTip ( tr ( "Расположить окна черепицей" ) ); connect ( tileAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( tile() ) ); cascadeAction = new QAction ( tr ( "Выстроить каскадом" ), this ); cascadeAction->setStatusTip ( tr ( "Выстроить окна каскадом" ) ); connect ( cascadeAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( cascade() ) ); nextAction = new QAction ( tr ( "Следующее окно" ), this ); nextAction->setShortcut ( tr ( "Ctrl+F6" ) ); nextAction->setStatusTip ( tr ( "Переместить фокус на следующее окно" ) ); connect ( nextAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( activateNextWindow() ) ); previousAction = new QAction ( tr ( "Предыдущее окно" ), this ); previousAction->setShortcut ( tr ( "Ctrl+Shift+F6" ) ); previousAction->setStatusTip ( tr ( "Переместить фокус на предыдущее окно" ) ); connect ( previousAction, SIGNAL ( triggered() ), symbolEditorWorkspace, SLOT ( activatePreviousWindow() ) ); separatorAction = new QAction ( this ); separatorAction->setSeparator ( true ); aboutSymbolEditorAction = new QAction ( tr ( "Про приложение" ), this ); aboutSymbolEditorAction->setStatusTip ( tr ( "Описание приложения" ) ); connect ( aboutSymbolEditorAction, SIGNAL ( triggered() ), this, SLOT ( about() ) ); aboutQtAction = new QAction ( tr ( "Про Qt" ), this ); aboutQtAction->setStatusTip ( tr ( "Показать информацию про Qt" ) ); connect ( aboutQtAction, SIGNAL ( triggered() ), qApp, SLOT ( aboutQt() ) ); windowActionGroup = new QActionGroup ( this ); } void MainWindow::createSymbolEditorMenus() { symbolEditorFileMenu = menuBar()->addMenu ( tr ( "Файл" ) ); symbolEditorFileMenu->addAction ( newSymbolAction ); symbolEditorFileMenu->addAction ( openSymbolAction ); symbolEditorFileMenu->addAction ( saveSymbolAction ); symbolEditorFileMenu->addAction ( saveSymbolAsAction ); symbolEditorFileMenu->addSeparator(); symbolEditorFileMenu->addAction ( exitAction ); symbolEditorEditMenu = menuBar()->addMenu ( tr ( "Править" ) ); symbolEditorEditMenu->addAction ( cutSymbolAction ); symbolEditorEditMenu->addAction ( copySymbolAction ); symbolEditorEditMenu->addAction ( pasteSymbolAction ); symbolEditorEditMenu->addSeparator(); symbolEditorEditMenu->addAction ( addNewSymbolText ); symbolEditorWindowMenu = menuBar()->addMenu ( tr ( "Окно" ) ); symbolEditorWindowMenu->addAction ( closeAction ); symbolEditorWindowMenu->addAction ( closeAllAction ); symbolEditorWindowMenu->addSeparator(); symbolEditorWindowMenu->addAction ( tileAction ); symbolEditorWindowMenu->addAction ( cascadeAction ); symbolEditorWindowMenu->addSeparator(); symbolEditorWindowMenu->addAction ( nextAction ); symbolEditorWindowMenu->addAction ( previousAction ); symbolEditorWindowMenu->addAction ( separatorAction ); menuBar()->addSeparator(); symbolEditorHelpMenu = menuBar()->addMenu ( tr ( "Помощь" ) ); symbolEditorHelpMenu->addAction ( aboutSymbolEditorAction ); symbolEditorHelpMenu->addAction ( aboutQtAction ); } void MainWindow::createSymbolEditorToolBars() { symbolEditorFileToolBar = addToolBar ( tr ( "Файл" ) ); symbolEditorFileToolBar->addAction ( newSymbolAction ); symbolEditorFileToolBar->addAction ( openSymbolAction ); symbolEditorFileToolBar->addAction ( saveSymbolAction ); symbolEditorEditToolBar = addToolBar ( tr ( "Редактирования" ) ); symbolEditorEditToolBar->addAction ( cutSymbolAction ); symbolEditorEditToolBar->addAction ( copySymbolAction ); symbolEditorEditToolBar->addAction ( pasteSymbolAction ); } void MainWindow::createSymbolEditorStatusBar() { readyLabel = new QLabel ( tr ( " Готово" ) ); statusBar()->addWidget ( readyLabel, 1 ); } SymbolEditor *MainWindow::createSymbolEditor() { qDebug("Run SymbolEditor *MainWindow::createSymbolEditor()"); SymbolEditor *symbolEditor = new SymbolEditor; connect ( symbolEditor, SIGNAL ( copyAvailable ( bool ) ), cutSymbolAction, SLOT ( setEnabled ( bool ) ) ); connect ( symbolEditor, SIGNAL ( copyAvailable ( bool ) ), copySymbolAction, SLOT ( setEnabled ( bool ) ) ); symbolEditorWorkspace->addWindow ( symbolEditor ); symbolEditorWindowMenu->addAction ( symbolEditor->symbolWindowMenuAction() ); windowActionGroup->addAction ( symbolEditor->symbolWindowMenuAction() ); qDebug("return symbolEditor %d",symbolEditor); return symbolEditor; } SymbolEditor *MainWindow::activeSymbolEditor() { return qobject_cast<SymbolEditor *> ( symbolEditorWorkspace ->activeWindow() ); } void MainWindow::addText() { // добавить текст на сцену symbolEditorScene, правильно? }
mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow>
class QAction;
class QActionGroup;
class QLabel;
class QMenu;
class QToolBar;
class QWorkspace;
class SymbolEditor;
class MainWindow : public QMainWindow { Q_OBJECT
public: MainWindow();
public slots: void newFile();
void openFile ( const QString &fileName );
protected: void closeEvent ( QCloseEvent *event );
private slots: void addText();
void open();
void save();
void saveAs();
void cut();
void copy();
void paste();
void about();
void updateSymbolEditorMenus();
private: void createSymbolEditorActions();
void createSymbolEditorMenus();
void createSymbolEditorToolBars();
void createSymbolEditorStatusBar();
SymbolEditor *createSymbolEditor();
SymbolEditor *activeSymbolEditor();
QWorkspace *symbolEditorWorkspace;
QLabel *readyLabel;
QWidgetList windows;
QMenu *symbolEditorFileMenu;
QMenu *symbolEditorEditMenu;
QMenu *symbolEditorWindowMenu;
QMenu *symbolEditorHelpMenu;
QToolBar *symbolEditorFileToolBar;
QToolBar *symbolEditorEditToolBar;
QActionGroup *windowActionGroup;
QAction *addNewSymbolText;
QAction *newSymbolAction;
QAction *openSymbolAction;
QAction *saveSymbolAction;
QAction *saveSymbolAsAction;
QAction *exitAction;
QAction *cutSymbolAction;
QAction *copySymbolAction;
QAction *pasteSymbolAction;
QAction *closeAction;
QAction *closeAllAction;
QAction *tileAction;
QAction *cascadeAction;
QAction *nextAction;
QAction *previousAction;
QAction *separatorAction;
QAction *aboutSymbolEditorAction;
QAction *aboutQtAction; };
#endif
symboleditor.cpp #include <QtGui> #include <QFileDialog> //#include <QGraphicsScene> #include "symboleditor.h"
SymbolEditor::SymbolEditor(QWidget *parent) : QGraphicsView(parent) { qDebug("Run Constructor SymbolEditor"); symbolEditorScene = new QGraphicsScene(this); qDebug("Run Constructor QGraphicsScene %d",symbolEditorScene); symbolEditorScene->addText("Test!"); symbolEditorView = new QGraphicsView(); symbolEditorView->setScene(symbolEditorScene); symbolEditorView->setRenderHint(QPainter::Antialiasing); symbolEditorView->setCacheMode(QGraphicsView::CacheBackground); symbolEditorView->show(); symbolAction = new QAction(this); symbolAction->setCheckable(true); connect(symbolAction, SIGNAL(triggered()), this, SLOT(show())); connect(symbolAction,SIGNAL(triggered()), this,SLOT(setFocus()));
isUntitled = true; modified=false; selected=false; fileSymbolFilters = tr("Файлы символов УГО (*.ksef)\n" "Все файлы (*)"); // проверить connect(this, SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));
symbolEditorView->setWindowIcon(QPixmap(":/images/document.png")); //WARNUNG заменить иконку symbolEditorView->setAttribute(Qt::WA_DeleteOnClose); }
void SymbolEditor::newSymbolFile() { static int documentNumber = 1;
curSymbolFile = tr("symbol%1.ksef").arg(documentNumber); setWindowTitle(curSymbolFile + "[*]"); symbolAction->setText(curSymbolFile); isUntitled = true; ++documentNumber; }
bool SymbolEditor::openSymbol() { QString fileName = QFileDialog::getOpenFileName(this, tr("Открыть файл символа УГО"), ".",fileSymbolFilters); if (fileName.isEmpty()) return false;
return openSymbolFile(fileName); }
bool SymbolEditor::openSymbolFile(const QString &fileName) { if (readSymbolFile(fileName)) { setCurrentSymbolFile(fileName); return true; } else { return false; } }
bool SymbolEditor::saveSymbol() { if (isUntitled) { return saveSymbolAs(); } else { return saveSymbolFile(curSymbolFile); } }
bool SymbolEditor::saveSymbolAs() { QString fileName = QFileDialog::getSaveFileName(this, tr("Сохранить файл символа УГО как"), curSymbolFile, fileSymbolFilters); if (fileName.isEmpty()) return false;
return saveSymbolFile(fileName); }
void SymbolEditor::closeEvent(QCloseEvent *event) { if (okToContinue()) { event->accept(); } else { event->ignore(); } }
void SymbolEditor::documentWasModified() { setWindowModified(true); }
bool SymbolEditor::okToContinue() { if (isModified()) { int r = QMessageBox::warning(this, tr("SymbolEditor Редактор символов УГО"), tr("Файл %1 был изменен.\n" "Сохранить изменения?") .arg(strippedName(curSymbolFile)), QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); if (r == QMessageBox::Yes) { return saveSymbol(); } else if (r == QMessageBox::Cancel) { return false; } } return true; }
bool SymbolEditor::saveSymbolFile(const QString &fileName) { if (writeSymbolFile(fileName)) { setCurrentSymbolFile(fileName); return true; } else { return false; } }
void SymbolEditor::setCurrentSymbolFile(const QString &fileName) { curSymbolFile = fileName; isUntitled = false; symbolAction->setText(strippedName(curSymbolFile)); // ???? setWindowModified(false); // ???? setWindowTitle(strippedName(curSymbolFile) + "[*]"); setWindowModified(false); }
bool SymbolEditor::readSymbolFile(const QString &fileName) { // QFile file(fileName); // if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // QMessageBox::warning(this, tr("SymbolEditor Редактор символов УГО"), // tr("Не могу прочитать файл %1:\n%2.") // .arg(file.fileName()) // .arg(file.errorString())); // return false; // }
// QTextStream in(&file); // QApplication::setOverrideCursor(Qt::WaitCursor); // setPlainText(in.readAll()); // QApplication::restoreOverrideCursor(); emit contentsChanged(); modified=true; return true; }
bool SymbolEditor::writeSymbolFile(const QString &fileName) { // QFile file(fileName); // if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { // QMessageBox::warning(this, tr("SymbolEditor Редактор символов УГО"), // tr("Не могу записать файл %1:\n%2.") // .arg(file.fileName()) // .arg(file.errorString())); // return false; // } // // QTextStream out(&file); // QApplication::setOverrideCursor(Qt::WaitCursor); // out << document()->toPlainText(); // QApplication::restoreOverrideCursor(); modified=false; return true; }
QString SymbolEditor::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } void SymbolEditor::cutSymbol() { // emit contentsChanged(); modified=true; } void SymbolEditor::copySymbol() { // } void SymbolEditor::pasteSymbol() { // emit contentsChanged(); modified=true; }
symboleditor.h #ifndef SYMBOLEDITOR_H #define SYMBOLEDITOR_H #include <QGraphicsView>
class SymbolEditor : public QGraphicsView { Q_OBJECT
public: SymbolEditor ( QWidget *parent = 0 ); void newSymbolFile(); bool openSymbol();
bool openSymbolFile ( const QString &fileName );
bool saveSymbol();
bool saveSymbolAs();
QAction *symbolWindowMenuAction() const { return symbolAction; }
bool isModified()
{ return modified; }
void setModified ( bool ) { modified = true; }
bool isSelected() { return selected; }
protected: void closeEvent ( QCloseEvent *event );
signals: void copyAvailable ( bool ); void contentsChanged();
public slots: void documentWasModified(); void cutSymbol(); void copySymbol(); void pasteSymbol(); private: bool okToContinue();
bool saveSymbolFile ( const QString &fileName );
void setCurrentSymbolFile ( const QString &fileName );
bool readSymbolFile ( const QString &fileName );
bool writeSymbolFile ( const QString &fileName );
QString strippedName ( const QString &fullFileName );
QString curSymbolFile;
bool isUntitled;
QString fileSymbolFilters;
QAction *symbolAction;
QGraphicsView *symbolEditorView;
QGraphicsScene *symbolEditorScene;
bool modified;
bool selected; };
#endif
main.cpp #include <QApplication> #include <QTextCodec> #include "mainwindow.h"
int main ( int argc, char *argv[] ) { QApplication app ( argc, argv ); QStringList args = app.arguments(); QTextCodec::setCodecForTr ( QTextCodec::codecForName ( "utf8" ) ); MainWindow mainWin;
if ( args.count() > 1 ) { for ( int i = 1; i < args.count(); ++i ) mainWin.openFile ( args[i] );
} else { mainWin.newFile(); }
mainWin.show();
return app.exec(); }
Да простит меня модератор за длиннй листинг. В результате работы программы я получаю два отдельных окна, второе не связано с редактором. Помогите, плиз!
Название: Qt 4.2.2 Как скрестить MDI с Graphics View framework
Отправлено: Alex00 от Февраль 12, 2007, 10:49
Да, многовато. Мало кто захочет все разбирать.
Название: Qt 4.2.2 Как скрестить MDI с Graphics View framework
Отправлено: Admin от Февраль 12, 2007, 17:48
давай по шагам - пока без граффики ты смотрел ли примеры QT там есть пример MDI
Название: Qt 4.2.2 Как скрестить MDI с Graphics View framework
Отправлено: Kuzemko от Февраль 13, 2007, 08:07
давай по шагам - пока без граффики ты смотрел ли примеры QT там есть пример MDI Пример смотрел (на основе его делал). Все работае кроме графики. У меня подозрения что я не правильно сделал конструктор для окна редактора SymbolEditor::SymbolEditor(QWidget *parent) : QGraphicsView(parent) { qDebug("Run Constructor SymbolEditor"); symbolEditorScene = new QGraphicsScene(this); qDebug("Run Constructor QGraphicsScene %d",symbolEditorScene);
symbolEditorScene->addText("Test!");
symbolEditorView = new QGraphicsView(); symbolEditorView->setScene(symbolEditorScene); symbolEditorView->setRenderHint(QPainter::Antialiasing); symbolEditorView->setCacheMode(QGraphicsView::CacheBackground); symbolEditorView->show(); symbolAction = new QAction(this); symbolAction->setCheckable(true); connect(symbolAction, SIGNAL(triggered()), this, SLOT(show())); connect(symbolAction,SIGNAL(triggered()), this,SLOT(setFocus()));
isUntitled = true; modified=false; selected=false; connect(this, SIGNAL(contentsChanged()),this, SLOT(documentWasModified())); symbolEditorView->setAttribute(Qt::WA_DeleteOnClose); }
|