Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ Плавающие QDockWidget.

Автор: NordWest 23.10.2009, 15:12

Здравствуйте!

Есть QMainWindow и множество QDockWidget, которые при запуске прячутся и показываются по мере необходимости. Набор панелек такой. При этом удобно весьма получается иногда прикрепить их к окну по краям в различных сочетаниях, на вкладках. Делается это автоматом при манипуляциях с переносом. А вот как бы иметь возможность запомнить: что и как понавешано, чтобы при следующем открытии не приходилось снова всё распихивать?

Автор: fsMark 23.10.2009, 15:26

Цитата(NordWest @ 23.10.2009, 16:12) *
А вот как бы иметь возможность запомнить: что и как понавешано, чтобы при следующем открытии не приходилось снова всё распихивать?

http://doc.crossplatform.ru/qt/4.6.x/qmainwindow.html#saveState, и это значение сохранить в реестр, востанавливается http://doc.crossplatform.ru/qt/4.6.x/qmainwindow.html#restoreState

Автор: JuryS1806 23.10.2009, 20:44

// Вот собственно две функции, которые через диалоговые окна открытия и сохранения файлов сохраняют
// лэйаут и геометрию всех виджетов. Проверено в M$ Windows и Linux .

void MainWindow::savePanels()
{
    QString DirToSaveAs = QDir::homePath();
    QString fileName
        = QFileDialog::getSaveFileName(this, trUtf8("Сохранить расположение панелей как..."),DirToSaveAs,trUtf8( "Параметры панелей (*.pan)"));
    if (fileName.isEmpty())
        return;
    QFile file(QString(fileName+".pan"));
    if (!file.open(QFile::WriteOnly)) {
        QString msg = trUtf8("Ошибка при открытии файла %1\n%2")
                        .arg(fileName)
                        .arg(file.errorString());
        QMessageBox::warning(this, trUtf8("Ошибка"), msg);
        return;
    }

    QByteArray geo_data = saveGeometry();
    QByteArray layout_data = saveState();

    bool ok = file.putChar((uchar)geo_data.size());
    if (ok)
        ok = file.write(geo_data) == geo_data.size();
    if (ok)
        ok = file.write(layout_data) == layout_data.size();

    if (!ok) {
        QString msg = trUtf8("Ошибка записи в %1\n%2")
                        .arg(fileName)
                        .arg(file.errorString());
        QMessageBox::warning(this, trUtf8("Ошибка"), msg);
        return;
    }
}

void MainWindow::loadPanels()
{
    QString fileName
        = QFileDialog::getOpenFileName(this, trUtf8("Загрузить расположение панелей..."),("/"),trUtf8( "Параметры панелей (*.pan)"));
    if (fileName.isEmpty())
        return;
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        QString msg = trUtf8("Ошибка при чтении %1\n%2")
                        .arg(fileName)
                        .arg(file.errorString());
        QMessageBox::warning(this, trUtf8("Ошибка"), msg);
        return;
    }

    uchar geo_size;
    QByteArray geo_data;
    QByteArray layout_data;

    bool ok = file.getChar((char*)&geo_size);
    if (ok) {
        geo_data = file.read(geo_size);
        ok = geo_data.size() == geo_size;
    }
    if (ok) {
        layout_data = file.readAll();
        ok = layout_data.size() > 0;
    }

    if (ok)
        ok = restoreGeometry(geo_data);
    if (ok)
        ok = restoreState(layout_data);

    if (!ok) {
        QString msg = trUtf8("Ошибка при чтении %1")
                        .arg(fileName);
        QMessageBox::warning(this, trUtf8("Ошибка"), msg);
        return;
    }
}

Автор: Litkevich Yuriy 23.10.2009, 20:54

Цитата(fsMark @ 23.10.2009, 19:26) *
QMainWindow::saveState(), и это значение сохранить в реестр, восстанавливается QMainWindow::restoreState()
К этому надо ещё одну важную деталь добавлять, сохраняться/восстанавливаться будут только те виджеты для которых задано имя объекта, через setObjectName (как это "делает" Дизайнер)

Автор: JuryS1806 1.11.2009, 22:14

Это точно ! если не назначить имя объекта, срабатывает как-то странно . Спасибо за подсказку.

Автор: DEADHUNT 1.11.2009, 22:23

раз тема про QDockWidget есть тоже вопрос. есть много QDockWidget`s соединённых через tabifyDockWidget как можно показать определённый DockWidget?

Автор: Litkevich Yuriy 1.11.2009, 22:42

Цитата(DEADHUNT @ 2.11.2009, 1:23) *
есть много QDockWidget`s соединённых через tabifyDockWidget как можно показать определённый DockWidget?
поищи по форуму, кто-то основательно озадачивался вопросом программного управления QDockWidget`ов, не помню кто именно.

Автор: SABROG 2.11.2009, 12:41

Цитата(Litkevich Yuriy @ 1.11.2009, 22:42) *
Цитата(DEADHUNT @ 2.11.2009, 1:23) *
есть много QDockWidget`s соединённых через tabifyDockWidget как можно показать определённый DockWidget?
поищи по форуму, кто-то основательно озадачивался вопросом программного управления QDockWidget`ов, не помню кто именно.

Кто же еще мог http://www.forum.crossplatform.ru/index.php?s=&showtopic=1883 :lol:
В блоге даже http://vingrad.ru/blogs/sabrog/2008/12/26/qt-44-opredelyaem-vidimyie-qdockwidgetyi/ по этому поводу. И http://vingrad.ru/blogs/sabrog/2008/12/26/qt-opredelyaem-tekuschiy-vidzhet-v-qtabbar-qdockwidgetov/ еще, чтобы показать нужный виджет.

Автор: Litkevich Yuriy 2.11.2009, 16:22

Цитата(SABROG @ 2.11.2009, 15:41) *
Кто же еще мог заморачиваться
извини из головы выпало :)

Автор: DEADHUNT 2.11.2009, 17:27

Цитата(SABROG @ 2.11.2009, 12:41) *
Кто же еще мог http://www.forum.crossplatform.ru/index.php?s=&showtopic=1883 :lol:
В блоге даже http://vingrad.ru/blogs/sabrog/2008/12/26/qt-44-opredelyaem-vidimyie-qdockwidgetyi/ по этому поводу. И http://vingrad.ru/blogs/sabrog/2008/12/26/qt-opredelyaem-tekuschiy-vidzhet-v-qtabbar-qdockwidgetov/ еще, чтобы показать нужный виджет.

в примере идёт определение текущего видимого QDockWidget`а через QTabBar, а мне надо что-то типа setCurrentIndex, setCurrentWidget из QTabWidget только для программного управления QDockWidget`ами

вообще-то ниже нашёл то что надо.

Автор: &-rey 28.11.2009, 21:50

подскажите каким образом можно сохранить QbyteArray в реестре ?
пробовал конвертитровать в String, не вышло, попробовал сделать так:

    QByteArray ba = saveState();
    settings.beginWriteArray("array");
    for (int i = 0; i < ba.size(); ++i)
    {
        settings.setArrayIndex(i);
        settings.setValue("index", ba.at(i));
    }
    settings.endArray();

но при его вычитке size = 0;
    QByteArray ba;
    int size = settings.beginReadArray("array");
    for (int i = 0; i < size; ++i)
    {
        settings.setArrayIndex(i);
        ba.append(settings.value("index").toInt());
    }
    settings.endArray();
    restoreState(ba);

сами методы обрабатываются корректно.

Автор: &-rey 29.11.2009, 14:55

ошибка найдена, не сохранялось в реесте, и сохранение можно сделать проще.

Автор: NordWest 14.12.2009, 11:40

Цитата(JuryS1806 @ 23.10.2009, 21:44) *
// Вот собственно две функции, которые через диалоговые окна открытия и сохранения файлов сохраняют
// лэйаут и геометрию всех виджетов. Проверено в M$ Windows и Linux .


Спасибо, то что надо. Только под виндой пришлось trUtf8() заменить на tr(), т.к. квадратики выдавались. И (+".pan") убрал, т.к. имя получалось "*.pan.pan". Под Lin ещё не пробовал.
А так всё отлично. Спс!

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)