crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> QDockWidget & resize, Начальный размер для QDockWidget
DmP
  опции профиля:
сообщение 14.6.2009, 3:11
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 61
Регистрация: 11.3.2008
Пользователь №: 116

Спасибо сказали: 15 раз(а)




Репутация:   2  


Привет!
Вот задумался над тем, как задать начальный размер для QDockWidget. Не всегда хочется переопределять sizeHint().
Получился такой хак, позволяющий задать размер для нижнего дока, может кому пригодится:
#include <../src/gui/widgets/qmainwindowlayout_p.h>

MainForm::MainForm() : QMainWindow()
{
    setupUi(this);

    QMainWindowLayout* mwl = 0;
    const QObjectList& list = children();
    for (int i=0; i<list.size(); i++)
    {
        QObject* o = list.at(i);
        if (qstrcmp(o->metaObject()->className(), "QMainWindowLayout") == 0)
        {
            mwl = (QMainWindowLayout*)o;
            break;
        }
    }
    if (mwl)
    {
        QDockAreaLayout& dal = mwl->layoutState.dockAreaLayout;
        dal.docks[QInternal::BottomDock].rect = QRect(0, 0, 0, 100);
    }
}

Да, код написан на Qt 4.5.1
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 13:56
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Я сделал небольшой моддинг твоего кода сократив его до одной строки :)

(((QMainWindowLayout *)layout())->layoutState.dockAreaLayout).docks[QInternal::BottomDock].rect = QRect(0, 0, 0, 100);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 14:41
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 61
Регистрация: 11.3.2008
Пользователь №: 116

Спасибо сказали: 15 раз(а)




Репутация:   2  


SABROG, был у меня вариант с layout(), но отладчик упорно не хотел сознаваться в том, какое настоящее имя класса и в процессе разбора полетов этот вариант потерялся. Сейчас сократил код до:
    QMainWindowLayout* mwl = (QMainWindowLayout*)layout();
    if (mwl)
    {
        QDockAreaLayout& dal = mwl->layoutState.dockAreaLayout;
        dal.docks[QInternal::BottomDock].rect = QRect(0, 0, 0, 100);
    }

У меня потом будет левая и правая панелька.
А для однострочного варианта, одна скобка лишняя ;)
((QMainWindowLayout*)layout())->layoutState.dockAreaLayout.docks[QInternal::BottomDock].rect = QRect(0, 0, 0, 100);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 15:19
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(DmP @ 14.6.2009, 15:41) *
А для однострочного варианта, одна скобка лишняя ;)

Поспорим, что нет? ;)

Цитата(DmP @ 14.6.2009, 15:41) *
SABROG, был у меня вариант с layout(), но отладчик упорно не хотел сознаваться в том, какое настоящее имя класса

А я просто обошел рекурсией всё дерево и потом сравнил указатели. Кстати еще такой вариант работает:

QObject *o = findChild<QObject *>("_layout");


Сообщение отредактировал SABROG - 14.6.2009, 15:25
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 17:29
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 61
Регистрация: 11.3.2008
Пользователь №: 116

Спасибо сказали: 15 раз(а)




Репутация:   2  


Цитата(SABROG @ 14.6.2009, 16:19) *
Цитата(DmP @ 14.6.2009, 15:41) *
А для однострочного варианта, одна скобка лишняя ;)

Поспорим, что нет? ;)

У меня работает. :)

Цитата(SABROG @ 14.6.2009, 16:19) *
А я просто обошел рекурсией всё дерево и потом сравнил указатели. Кстати еще такой вариант работает:

QObject *o = findChild<QObject *>("_layout");

Но никто не гарантирует, что они вдруг не поменяют имя объекта.
Странно то, что по идее самый правильный вариант:
QMainWindowLayout* o = findChild<QMainWindowLayout*>();

Компилируется, но не линкуется, видимо не все полезное экспортируется.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 17:43
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(DmP @ 14.6.2009, 18:29) *
У меня работает. :)


В каком виде?

Цитата(DmP @ 14.6.2009, 18:29) *
Странно то, что по идее самый правильный вариант:


О ровно такой же правильный как и жесткая привязка к названию объекта "_layout" и вообще как и сам хак. :)

Кстати почему такое не работает?

dal.docks[QInternal::BottomDock].rect.setHeight(100);


Сообщение отредактировал SABROG - 14.6.2009, 17:46
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 14.6.2009, 18:20
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(SABROG @ 14.6.2009, 18:43) *
Кстати почему такое не работает?

dal.docks[QInternal::BottomDock].rect.setHeight(100);

Это только предположение, я не проверял.
Думаю это из-за того, что rect может быть не валиден ( height <= 0 || width <= 0 ). Конструктор по умолчанию, как раз создает такую область.
В этом случае, ты устанавливаешь height, а width не изменяется.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 19:03
Сообщение #8


Студент
*

Группа: Участник
Сообщений: 61
Регистрация: 11.3.2008
Пользователь №: 116

Спасибо сказали: 15 раз(а)




Репутация:   2  


Цитата(SABROG @ 14.6.2009, 18:43) *
В каком виде?

Вот так, как и написано: :unknw:
((QMainWindowLayout*)layout())->layoutState.dockAreaLayout.docks[QInternal::BottomDock].rect = QRect(0, 0, 0, 100);
А зачем dockAreaLayout в скобки брать?

Цитата(SABROG @ 14.6.2009, 18:43) *
О ровно такой же правильный как и жесткая привязка к названию объекта "_layout" и вообще как и сам хак. :)

О нет, поменять имя класса проблематично, нужно править кучу кода. А поменять имя объекта - всего одна строка и ни чему это не повредит.
А то, что хак может перестать работать в любой следующей версии, так это да, не спорю. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 20:06
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Цитата(DmP @ 14.6.2009, 20:03) *
А зачем dockAreaLayout в скобки брать?

А хрен его знает, наверно планировал приводить к другому указателю, я вообще думал, что ты об этих "())->" :)

Просто если кому интересно, то тролли в своем факе предлагают sizeHint переопределять у виджета, который будет помещаться на доквиджет: http://www.qtsoftware.com/developer/faqs/550

Цитата(BRE @ 14.6.2009, 19:20) *
Это только предположение


Скорее всего ты прав, на этапе создания главной формы детки еще не знают своего rect'a.

QRect(0,0 -1x-1) //в констукторе окна
QRect(0,315 352x20) //в цикле событий


Соответственно так все работает
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Q_INVOKABLE void afterEnterToLoop();
private:
    Ui::MainWindowClass *ui;
};


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindowClass)
{
    ui->setupUi(this);
    QMetaObject::invokeMethod(this, "afterEnterToLoop", Qt::QueuedConnection);
}

void MainWindow::afterEnterToLoop()
{
    ((QMainWindowLayout *)layout())->layoutState.dockAreaLayout.docks[QInternal::BottomDock].rect.setHeight(100);
}


P.S.: кстати я так и не понял зачем это нужно. Зачем устанавливать предварительный размер пустому доквиджету? Зачем вообще в программе нужен пустой доквиджет? Рисовать на нем чтоль? На худой конец работает setMinimumHeight() для виджета. А если не пустой, то он всё равно изменится при размещении в него виджетов. А там можно и setMinimumHeight отрубить при добавлении.

Сообщение отредактировал SABROG - 14.6.2009, 20:38
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 21:26
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 61
Регистрация: 11.3.2008
Пользователь №: 116

Спасибо сказали: 15 раз(а)




Репутация:   2  


Цитата(SABROG @ 14.6.2009, 21:06) *
P.S.: кстати я так и не понял зачем это нужно. Зачем устанавливать предварительный размер пустому доквиджету? Зачем вообще в программе нужен пустой доквиджет? Рисовать на нем чтоль? На худой конец работает setMinimumHeight() для виджета. А если не пустой, то он всё равно изменится при размещении в него виджетов. А там можно и setMinimumHeight отрубить при добавлении.

А кто сказал что он пустой? ;) И уж тем более я не предлагал таким методом изменять размер док-виджета после его появления. А setMinimumHeight() зачем? что бы потом нельзя было уменьшить док?
Была тривиальная задача, при создании QMainWindow, расставить док-виджеты с нужными мне размерами, при этом оставляя возможность менять размер их в дальнейшем, и не переопределяя sizeHint() у QTableWidget и у QTextEdit.
SABROG, если тебе не понятно зачем это все, так зачем ты начал это все использовать? :)

Да следует уточнить, что данный метод должен вызываться, после создания всех доков. И действует не на какой то док отдельно, а в целом задет размер стороны, в данном случай всех нижних. Работает аналогично QMainWindow::restoreState().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 23.11.2024, 6:12