Qt5 i dopasowywujące się i układające się widgety

0

Witajcie,

Piszę program w Qt5. Uczę się z oficjalnej strony Qt i jeszcze dużo nie wiem. Piszę "z palca", a nie Designerem. Chcę zrobić okno do edytora materiałów w programie do modeli 3d. Chcę mieć widget OpenGL, który sam znajdzie swoje miejsce na górze okna, a obok niego będzie się znajdować QListView domyślnie te dwa podzielone po pół szerokości okna. QScrollBar, którzy sam znajdzie swoje miejsce i wymiary na dole okna. Między tymi trzema widgetami miały by się znajdować linie, które miały by pozwalać na zmianę podziału wymiarów między widgetami według użyszkodnika programu. Oto obrazek, który pomoże to wszystko sobie wyobrazić:
4p.png
Chodzi o zachowanie podobne do QDockWindow, tylko, że bez możliwości "wyjęcia" dokowanego okienka na zewnątrz i bez jego nazwy. Nie chodzi o gotowy kod tylko o jakich metod/klas użyć.

PS. Jest jakieś miejsce, gdzie można znaleźć zdjęcia poszczególnych widgetów Qt (klas dziedziczących po QWidget) jak wyglądają. Na oficjalnej stronie są opisy klas, ale nie znalazłem screenshotów. To zaoszczędziło by takich poszukiwań.

0

Qt jest niestety strasznie upierdliwe pod tym względem, i to co np. w WinForms jest trywialne, tutaj wymaga mnóstwo pracy i nerwów.

Piszę "z palca", a nie Designerem.
To może odpal Designera i spróbuj wyklikać to czego potrzebujesz. Jak już potrafisz wyklikać, to i sam napiszesz równoważny kod - albo, mając działającego gotowca, przekonasz się do Designera ;-)

0

Nie, nie trzeba pisać klas. Odpal Designera i się nim pobaw, zobacz co i jak działa.

0

Wolał bym jednak wiedzieć od strony kodu jak to działa. Wyklikiwaniem zajął bym się później jak będę wiedział jak to od strony kodu działa. zyli do tego trzeba użyć jakiegoś widgetu coś jak QDockWidget? Czy może każda klasa co dziedziczy po QWidget ma wbudowane "przyleganie" do ścian. Albo chociaż jakiego hasła po angielsku szukać do takiego zachowania widgetów?

1

Spróbuj jak proponuje Azarien. Wyklikaj sobie układ w Designerze, potem w plikach źródłowych wyszukaj pliku ui_***.h (gwiazdki to nazwa twojej klasy okna, np ui_mainwindow.h). Tam będziesz miał po kolei jak kodowo tworzony jest układ UI. Tak myślę, że to co chcesz osiągnąć, to odpowiednie rozmieszczenie widgetów w layot'ach(gridlayout, horizlayout, vertlayout, itp) i splitterach. Na formatce zaznaczasz widgety, ppm i z menu: rozmieść w ...

2

To jest proste jak konstrukcja cepa.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
      QSplitter *spliterH = new QSplitter(Qt::Vertical);
      setCentralWidget(spliterH); // jeśli to ma być main widnow
      QSplitter *spliterV =  new QSplitter(Qt::Horizontal);
      spliterH->addWidget(spliterV);
      spliterH->addWidget(new OptionsEditors());
      
      openGL = new QOpenGLWidget();
      spliterV->addWidget(openGL);
      spliterV->addWidget(new OptionSCheckboxes());
}

http://doc.qt.io/qt-5/qsplitter.html#details

0

Zrobiłem klasę, która dziedziczy po QWidget. Ma swoje własne atrybuty QSplitter, które są użyte tak jak @up tylko, że bez setCentralWidget() i te splitttery się nie pojawiają w nowym oknie. Wcześniej okno wypełniało się tłem z innych programów jak dziedziczyło po QWindow (wtf?), teraz jak dziedziczy po QWidget wypełnia się na szaro. W konstruktorze nowej klasy dziedziczącej po QWidget zrobiłem kopiowanie do konstruktora QWidget i stworzyłem tam ów splittery.

/* HPP */
class MatWindow : public QWidget{
    QListWidget* matList;
    QScrollBar* properties;
    OpenGLWidget* preview;
    QSplitter* splitterHor;
    QSplitter* splitterVert;

    void createSplitter();
public:
    explicit MatWindow(QWidget * parent = 0, Qt::WindowFlags f = 0);
    ~MatWindow();
};

/* CPP */
MatWindow::MatWindow(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f)
{
    preview = new OpenGLWidget();
    matList = new QListWidget();
    properties = new QScrollBar();

    createSplitter();
}

void MatWindow::createSplitter()
{
    splitterHor = new QSplitter();
    splitterVert = new QSplitter(Qt::Vertical);

    splitterVert->addWidget(preview);
    splitterVert->addWidget(matList);
    splitterHor->addWidget(splitterVert);
    splitterHor->addWidget(properties);
}
3

Do poprawki:

void MatWindow::createSplitter()
{
    splitterHor = new QSplitter();
    new QHBoxLayout(this)->addWidget(splitterHor); // tego brakowało!

    splitterVert = new QSplitter(Qt::Vertical);
 
    splitterVert->addWidget(preview);
    splitterVert->addWidget(matList);
    splitterHor->addWidget(splitterVert);
    splitterHor->addWidget(properties);
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1