Приобрести книгу можно на сайте ozon.ru и в электронном виде на Google Play:
18 thoughts on “Глава 34 – Главное окно, создание SDI- и MDI-приложений”
Здравствуйте.
Листинг 34.9 “Определение класса SDIProgram”, стр 487.
В определение класса подключается само определение класса ( #include “SDIProgram.h”). В электронном архиве данной строчки нет, вероятно опечатка.
В примере MDI приложения, в слотах MDIProgram::slotSave() и MDIProgram::slotSaveAs() закралась ошибка:
DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow());
а должно быть:
DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()->widget());
Спасибо, Виталий! Да это действительно ошибка в методах MDIProgram::slotSave() и MDIProgram::slotSaveAs() нужно вызвать метод QMdiSubWindow::widget(), чтобы получить расположенные в дочерних окнах QMdiSubWindow виджеты. Тоесть в исходном коде необходимо заменить строчки DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()) на DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()->widget());
Здравствуйте, Макс!
На стр. 483 в листинге 34.3 функция loadModules(QSplashScreen*) завершается строчкой qApp->processEvents(). Объясните, пожалуйста, для чего нужна эта строчка?
Здравствуйте, Вячеслав! Это сделанно для того что бы дать немного “воздуха” и дать возможность приложению обработать события. Ведь мы сделали искуственно задержку при помощи цикла, и как бы создали имитацию загрузки модулей или плагинов, которые занимают время для загрузки у больших программных продуктов. Если бы мы не встроили возможность для отработки событий то в Windows мы бы увидели крутящиеся песочные часы и быть может еще в добавок сообщение о том что приложение не реагирует, а на Mac вращающуюся спираль.
Здравствуйте, Макс!
Может кому будет интересно. Вот так можно поменять слот slotChangeWindowsTitle (см. листинг 34.9), чтобы в заголовке окна отображалось только имя файла (без пути):
Макс, здравствуйте!
В программе “MDI Program” стр. 488 – 496 есть небольшой баг. Если пытаться сохранять файл, если не создано ни одного MDI-окна (документа), то приложение аварийно завершается. Варианты решения этой проблемы – это при запуске приложения создавать один пустой документ, либо в конструкторе класса MDIProgram делать неактивным (pactSave->setDisabled(true)) соответствующий “экшн”, и делать его активным, когда создается документ. Но тогда эта проблема проявится, когда пользователь закроет все открытые документы и попробует нажать “сохранить”. Какую “защиту от дурака” можно сделать в данном случае?
Здравствуйте, Вячеслав!
Самое правильное, как вы и сказали, это сделать объект QAction “Save” неактивным, причем это состояние должно устанавливаться всякий раз, когда в приложениий не имеет окон для редатирования.
Уважаемый Макс, Вы уж извините, но эта глава очень много вопросов вызвала у меня… Для закрытия приложения можно использовать статический слот quit() (например: qApp->quit() ), а можно closeAllWindows() (Вы его используете в коде своего приложения MDI ). Что предпочтительнее и для каких случаев? Спасибо!
Здравствуйте, Вячеслав! Думаю что придпочтительнее будет qApp->quit(), так как у приложения совсем не обязательно могут быть окна, напроимер приложение SystemTray или консольное. А qApp->quit() сработает во всех случаях.
Здравствуйте! На странице 478 книги есть текст “растровое изображение — массив растровых данных, хранящихся в файле формата ХРМ”, но в примере, который идёт вместе с книгой, ресурсы, на самом деле, хранятся в формате PNG.
Большое спасибо Дмитрий, Вы нашли артефакт из прошлых изданий. XPM формат уже в этой книге нигде не должен использоваться, все используемые в примерах файлы находятся в ресурсе проекта в формате PNG либо JPG.
Здравствуйте.
Листинг 34.9 “Определение класса SDIProgram”, стр 487.
В определение класса подключается само определение класса ( #include “SDIProgram.h”). В электронном архиве данной строчки нет, вероятно опечатка.
Спасибо Артем! Да, это действительно опечатка #include”SDIProgramm.h” в этом листинге не должно быть.
В примере MDI приложения, в слотах MDIProgram::slotSave() и MDIProgram::slotSaveAs() закралась ошибка:
DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow());
а должно быть:
DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()->widget());
Спасибо, Виталий! Да это действительно ошибка в методах MDIProgram::slotSave() и MDIProgram::slotSaveAs() нужно вызвать метод QMdiSubWindow::widget(), чтобы получить расположенные в дочерних окнах QMdiSubWindow виджеты. Тоесть в исходном коде необходимо заменить строчки DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()) на DocWindow* pdoc = qobject_cast(m_pma->activeSubWindow()->widget());
На стр. 477 в приведенном коде строчка “pmnu->addAction(pactSave)”, а должна быть “pmnuFile->addAction(pactSave)”.
Это опечатка. Должно быть pmnuFile->addAction(pactSave). Спасибо!
На стр. 479 в разделе “Доки” приведен код: “QLabel* plbl = new QLabel(“Label in Dock”, pdoc)”, вместо “pdoc” должно быть “pdock”.
Это опечатка. Должно быть QLabel(“Label in Dock”, pdock). Спасибо!
Здравствуйте, Макс!
На стр. 483 в листинге 34.3 функция loadModules(QSplashScreen*) завершается строчкой qApp->processEvents(). Объясните, пожалуйста, для чего нужна эта строчка?
Здравствуйте, Вячеслав! Это сделанно для того что бы дать немного “воздуха” и дать возможность приложению обработать события. Ведь мы сделали искуственно задержку при помощи цикла, и как бы создали имитацию загрузки модулей или плагинов, которые занимают время для загрузки у больших программных продуктов. Если бы мы не встроили возможность для отработки событий то в Windows мы бы увидели крутящиеся песочные часы и быть может еще в добавок сообщение о том что приложение не реагирует, а на Mac вращающуюся спираль.
Здравствуйте, Макс!
Может кому будет интересно. Вот так можно поменять слот slotChangeWindowsTitle (см. листинг 34.9), чтобы в заголовке окна отображалось только имя файла (без пути):
void slotChangeWindowTitle(const QString& str) {
QRegExp rxp(“\\w+\\.?\\w+$”);
QString strTmp = str.mid(str.indexOf(rxp),str.length()-str.indexOf(rxp));
setWindowTitle(strTmp);
}
Макс, здравствуйте!
В программе “MDI Program” стр. 488 – 496 есть небольшой баг. Если пытаться сохранять файл, если не создано ни одного MDI-окна (документа), то приложение аварийно завершается. Варианты решения этой проблемы – это при запуске приложения создавать один пустой документ, либо в конструкторе класса MDIProgram делать неактивным (pactSave->setDisabled(true)) соответствующий “экшн”, и делать его активным, когда создается документ. Но тогда эта проблема проявится, когда пользователь закроет все открытые документы и попробует нажать “сохранить”. Какую “защиту от дурака” можно сделать в данном случае?
Здравствуйте, Вячеслав!
Самое правильное, как вы и сказали, это сделать объект QAction “Save” неактивным, причем это состояние должно устанавливаться всякий раз, когда в приложениий не имеет окон для редатирования.
Уважаемый Макс, Вы уж извините, но эта глава очень много вопросов вызвала у меня… Для закрытия приложения можно использовать статический слот quit() (например: qApp->quit() ), а можно closeAllWindows() (Вы его используете в коде своего приложения MDI ). Что предпочтительнее и для каких случаев? Спасибо!
Здравствуйте, Вячеслав! Думаю что придпочтительнее будет qApp->quit(), так как у приложения совсем не обязательно могут быть окна, напроимер приложение SystemTray или консольное. А qApp->quit() сработает во всех случаях.
Всё понятно, спасибо!
Здравствуйте! На странице 478 книги есть текст “растровое изображение — массив растровых данных, хранящихся в файле формата ХРМ”, но в примере, который идёт вместе с книгой, ресурсы, на самом деле, хранятся в формате PNG.
Большое спасибо Дмитрий, Вы нашли артефакт из прошлых изданий. XPM формат уже в этой книге нигде не должен использоваться, все используемые в примерах файлы находятся в ресурсе проекта в формате PNG либо JPG.