Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: QCasper от Март 13, 2007, 16:48



Название: tabifyDockWidget
Отправлено: QCasper от Март 13, 2007, 16:48
Почему то первый док как и положено пристыковывается к правой части окна, а второй оказывается в виде маленького прямоугольника вообще в левом верхнем углу заголовка, вместо того, чтобы затабиться поверх первого.

Код:
QDockWidget *dw1 = new QDockWidget("1", this);
QDockWidget *dw2 = new QDockWidget("2", this);

addDockWidget(Qt::RightDockWidgetArea, dw1);
addDockWidget(Qt::RightDockWidgetArea, dw2);

tabifyDockWidget(dw1, dw2);


добавлено спустя 11 минут:

 Причем самое прикольное, что если напрямую вызывать этот код, будь он в функции или слоте, то все нормально работает. А если вызывать его через сигнал, то такая вот фигня...

добавлено спустя 14 минут:

 Вот короче:

Код:
#include "mainwindow.h"

#include <qaction.h>
#include <qdockwidget.h>
#include <qpushbutton.h>

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
QPushButton *btn = new QPushButton("Create docks", this);
setCentralWidget(btn);

connect(btn, SIGNAL(clicked()), this, SLOT(createDocks()));

// createDocks();
}
void MainWindow::createDocks() {
QDockWidget *dw1 = new QDockWidget("1", this);
QDockWidget *dw2 = new QDockWidget("2", this);

addDockWidget(Qt::RightDockWidgetArea, dw1);
addDockWidget(Qt::RightDockWidgetArea, dw2);

tabifyDockWidget(dw2, dw1);
}

если нажать на кнопку, то доки криво отобразяться, если напрямую из конструктора вызвать слот, то нормально. Баг?


Название: tabifyDockWidget
Отправлено: QCasper от Март 14, 2007, 14:18
Ну что, никаг, да? :(


Название: tabifyDockWidget
Отправлено: QCasper от Март 15, 2007, 17:13
Вот и в рассылке молчат, да и в 4.2.3 то же самое... :cry:


Название: tabifyDockWidget
Отправлено: alexis от Март 15, 2007, 21:10
IMHO, это происходит из-за того, что при создании объекта главного окна он пока еще ничего не знает о доках.

На практике проверено, что если в класс окна добавить мемберами эти доки, создать их в конструкторе, сделать их не видимыми, а затем, в слоте устанавливать положение дока и показывать их, то все работает более менее сносно.

Код:

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
           : QMainWindow(parent, flags)
{
        QPushButton *btn = new QPushButton("Create docks", this);
        setCentralWidget(btn);

        connect(btn, SIGNAL(clicked()), this, SLOT(createDocks()));


        dw1 = new QDockWidget("1", this);
        dw1->hide();
        dw2 = new QDockWidget("2", this);
        dw2->hide();

        //createDocks();
}

void MainWindow::createDocks()
{
        addDockWidget(Qt::RightDockWidgetArea, dw1);
        addDockWidget(Qt::RightDockWidgetArea, dw2);
        dw1->show();
        dw2->show();
        tabifyDockWidget(dw2, dw1);
}

[/code]


Название: tabifyDockWidget
Отправлено: QCasper от Март 16, 2007, 10:40
Цитата: "alexis"
IMHO, это происходит из-за того, что при создании объекта главного окна он пока еще ничего не знает о доках.

На практике проверено, что если в класс окна добавить мемберами эти доки, создать их в конструкторе, сделать их не видимыми, а затем, в слоте устанавливать положение дока и показывать их, то все работает более менее сносно.



Спасибо, манипуляции с показать/спрятать действительно помогли. Хотя дело и не в том, что "при создании объекта главного окна он пока еще ничего не знает о доках". Если раскоментировать в моем коде createDocks, то нормально же работает, несмотря на то, что в конструкторе.

У меня еще один вопрос. Как программно делать так, чтобы нужный мне док был сверху, когда они все затабифины? В рассылке я как-то наткался на этот вопрос. Ему вроде никто так и не ответил.

добавлено спустя 11 часов 31 минуту:

 Да, и как сделать чтобы табы были сверху/сбоку?


Название: tabifyDockWidget
Отправлено: alexis от Март 16, 2007, 19:57
Цитировать

Если раскоментировать в моем коде createDocks, то нормально же работает, несмотря на то, что в конструкторе

imho, не несмотря, а именно благодаря этому работает :)

Цитировать

Как программно делать так, чтобы нужный мне док был сверху, когда они все затабифины

подобная реализация есть в qt дизайнере. там доки можно совместить по драг-н-дроп.
как такое раелизуется - незнаю.


Название: tabifyDockWidget
Отправлено: QCasper от Март 17, 2007, 01:40
Цитата: "alexis"
Цитировать

Если раскоментировать в моем коде createDocks, то нормально же работает, несмотря на то, что в конструкторе

imho, не несмотря, а именно благодаря этому работает :)



Да нет, это просто я такой пример здесь написал, что все в конструкторе. На самом деле, в основном приложении, у меня все это делается после того, причем через достаточное кол-во времени, как создалось главное окно. И проблемы была именно в добавлени _подряд_ больше чем один док. Тот же самый слот нормально работал, если емитировать, подконнекченный к нему сигнал, не в цикле, а с паузой, по нажатию кнопки скажем.


Название: tabifyDockWidget
Отправлено: alexis от Март 19, 2007, 11:03
И как всегда: все гениальное - просто :)
Нижеследующий код - работает как ему и положено.
Вкратце: нужно вызывать обработчик событий приложения после вставки дока.

Код:

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
           : QMainWindow(parent, flags)
{
        QPushButton *btn = new QPushButton("Create docks", this);
        setCentralWidget(btn);

        connect(btn, SIGNAL(clicked()), this, SLOT(createDocks()));

        //createDocks();
}

void MainWindow::createDocks()
{
        QDockWidget *dw1 = new QDockWidget("1", this);
        addDockWidget(Qt::RightDockWidgetArea, dw1);

        QApplication::processEvents();

        QDockWidget *dw2 = new QDockWidget("2", this);
        addDockWidget(Qt::RightDockWidgetArea, dw2);

        QApplication::processEvents();

        tabifyDockWidget(dw2, dw1);
}



Название: tabifyDockWidget
Отправлено: QCasper от Март 19, 2007, 11:58
Вот кто бы мог подумать :D
Спасибо :)


Название: tabifyDockWidget
Отправлено: zaz80 от Май 10, 2007, 16:12
Цитировать

Как программно делать так, чтобы нужный мне док был сверху, когда они все затабифины


кто-нить все-таки знает, как это зделать???
и еще, как программно изменять ширину или высоту дока?


Название: Re: tabifyDockWidget
Отправлено: jack_r от Октябрь 09, 2009, 21:38
Ответ, конечно поздноват...  :) но надеюсь что пригодится, так как я потратил полдня  :P на то, чтобы решить
Как программно делать так, чтобы нужный мне док был сверху, когда они все затабифины
Для этого необходимо найти QTabBar доквиджета и в нем переключиться на нужную вкладку
Код:
void MainWindow::updateDock(int index)
{
  QTabBar *tabBar = findChild<QTabBar *>();
  tabBar->setCurrentIndex(index);
}
Но проблема в том, что этот способ будет работать лишь в том случае, если в главном окне только один таббар. Как быть если их несколько ???
Можно получить список всех потомков
Код:
QList<QTabBar *> tabBars = findChildren<QTabBar *>();
Но как определить какой из них относится к конкретной группе? tabBar->parent(), tabBar->parentWidget(), tabBar->objectName() и tabBar->metaObject()->... полезной для идентификации информации не сообщают. Как вариант, при создании вкладок последовательно устанавливать objectName() для таббаров и затем брать таббар с нужным именем.