crossplatform.ru

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

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
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 15)
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().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 21:41
Сообщение #11


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

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

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




Репутация:   34  


Цитата(DmP @ 14.6.2009, 22:26) *
А кто сказал что он пустой? ;)


Забавно, задача появившаяся из ниоткуда и ни для чего.

Цитата(DmP @ 14.6.2009, 22:26) *
SABROG, если тебе не понятно зачем это все, так зачем ты начал это все использовать? :)

А я и не начинал, увидел твой способ получения layout'а и задумался, а нет ли способа легче и нашел.
Цитата(DmP @ 14.6.2009, 22:26) *
Работает аналогично QMainWindow::restoreState().

Собственно почему бы тогда не разобрать этот QByteArray и не сэмулировать состояние виджетов, вместо использования хака?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 22:07
Сообщение #12


Студент
*

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

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




Репутация:   2  


Цитата(SABROG @ 14.6.2009, 22:41) *
Забавно, задача появившаяся из ниоткуда и ни для чего.

Это не задача :), это решение, посмотри первый пост.
А если интересно откуда она взялась такая задача, то можешь погуглить на тему "qdockwidget resize", этот вопрос многих мучает.
Цитата(SABROG @ 14.6.2009, 22:41) *
Собственно почему бы тогда не разобрать этот QByteArray и не сэмулировать состояние виджетов, вместо использования хака?

Такое решение есть в инете, но по сути этот, тот же хак, мне мое решение больше нравится.
Кстати, вопросы на эту тему и на этом форуме поднимались не раз, например:
http://www.forum.crossplatform.ru/index.ph...ckwidget+resize
или
http://www.forum.crossplatform.ru/index.ph...ckwidget+resize
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 14.6.2009, 22:46
Сообщение #13


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

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

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




Репутация:   34  


Цитата(DmP @ 14.6.2009, 23:07) *
можешь погуглить на тему "qdockwidget resize", этот вопрос многих мучает.


Кстати я заметил, что многих людей интересуют совершенно бесполезные вещи название которым "сделать красиво". Мало кто задает вопросы непосредственно по алгоритмам. Всем нужны стили, анимация, рюшечки, да еще чтобы это всё было кроссплатформенно.

Недавно человек на форуме вопрос задавал как адаптировать приложение под разные разрешения экрана на мобильнике. Я задумался и мне стало грустно, когда я вспомнил, что все размеры задаются не в процентах/соотношениях, а в пикселях. Был у меня старенький компьютер с монитором 14' я сидел на разрешении 800x600, проклинал программистов некоторых, которые писали программы на дельфи, не влезающие в мой экран.

А недавно погонял стиль "Skulpture" и понял, что все эти подгонки, цветов, размеров, шрифтов - коту под хвост при использовании разных стилей, т.к. каждый из них использует свои настройки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 14.6.2009, 23:13
Сообщение #14


Студент
*

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

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




Репутация:   2  


Цитата(SABROG @ 14.6.2009, 23:46) *
Кстати я заметил, что многих людей интересуют совершенно бесполезные вещи название которым "сделать красиво". Мало кто задает вопросы непосредственно по алгоритмам. Всем нужны стили, анимация, рюшечки, да еще чтобы это всё было кроссплатформенно.

Тут же дело не в красоте :), а в удобстве и простоте. Очень важно что бы программа сразу при запуске была пригодна для работы, а не так, что бы еще таскать и настраивать окошки. И нужен был простой способ задать размер QDockWidget, как например QSplitter::setSizes().
Почему такого важного метода нет, хотя такой метод выспрашивают у тролей еще с начальной 4.0 версии?

Сообщение отредактировал DmP - 14.6.2009, 23:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 15.6.2009, 9:04
Сообщение #15


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

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

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




Репутация:   34  


Цитата(DmP @ 15.6.2009, 0:13) *
Почему такого важного метода нет, хотя такой метод выспрашивают у тролей еще с начальной 4.0 версии?


Тут достаточно было бы метода setSizeHint для QWidget'a. Но вот тролли пока не могут его реализовать из-за различных факторов и конфузов, т.ч. ждать нам его придется до версии Qt 5.0 (это если они вообще решать его реализовывать): http://www.qtsoftware.com/developer/task-t...y&id=143749
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DmP
  опции профиля:
сообщение 15.6.2009, 10:41
Сообщение #16


Студент
*

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

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




Репутация:   2  


Цитата(SABROG @ 15.6.2009, 10:04) *
т.ч. ждать нам его придется до версии Qt 5.0

Да чем нам, подождем. :D
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 17.6.2025, 4:24