Dynamiczna wielkość okna QDialog

0

Witam ponownie :)

Chciałbym się zapytać, czy znacie funkcje, które pozwalają na to, aby rozmiar okna dostosował się do wielkości obiektu lub obiektów w nim. W obecnej chwili muszę okno rozciągnąć, aby zobaczyć cały obiekt. Dodam, że obiektem w QDialog jest MÓJ własny obiekt. Jest to zlepek QLabel i dwóch QRadioButton zawarłem go w QGroupBox. Obiekty te również umieszczam w oknie QDialog za pomocą QGridLayout

0

Mam u siebie bardzo podobna sytuację to znaczy QDialog, w nim QGroupBox i dynamicznie dodaje obiekty do okna dialogowego a ono dostosowuje swój rozmiar do zawartości...

Spróbuj ustawić w dialogu który jak mówisz ma QGridLayout opcje sizePolicy na expanding

0

Jeśli zrobiłeś poprawnie layouty to powinno wystarczyć:

dialog->setSize(dialog->sizeHint());

możesz też zmienić sizePolicy na QSizePolicy::Minimum albo QSizePolicy::Fixed albo ... http://qt-project.org/doc/qt-5.0/qtwidgets/qsizepolicy.html#Policy-enum.

0

coś mi to nie śmiga. W konstruktorze okna QDialog pisze:

this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
i nic się nie dzieje. Z kolei poniższy zapis:
this->setSizePolicy(QSizePolicy::Expanding);

Wyskakuje błąd, że
c:\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtGui\qsizepolicy.h:202: błąd:'QSizePolicy::QSizePolicy(int)' is private

0
  1. Poczytaj linka którego ci dałem, może bardziej potrzebujesz QSizePolicy::Minimum
  2. zapewne masz manualnie ustawiony rozmiar okna w designerze, we właściwościach okna znajdź size wyczyść wartość (jeśli dobrze pamiętam to pojawia się odpowiedni przycisk by to zrobić, gdy właściwość jest podświetlona; jak nie to taka opcja jest pod prawym przyciskiem myszy).
0

Co do linka to jestem w trakcie czytania.
Co do drugiej sugestii. Nie pisze przy pomocy desingera. Działam tylko w Qt creator, sam wszystko tworząc, zatem jak wykonać to programowo o czym wspomniałeś ?

0

zadziałało coś takiego
this->setFixedSize(this->width(),this->height());
Jednak nie ma to chyba nic wspólnego z QSizePolicy :|

0

najwyraźniej nie opisałeś dokładnie co chcesz osiągnąć.
Jeśli w swoim dialogu masz dynamiczną zawartość to ta linijka ustala twardo i na stałe wielkość okna i zmiana zawartości okna nie zmieni rozmiaru okna.

0

Chciałem, aby rozmiar okna Qdialog dostosowywał się do zawartości, która zależy ode mnie. Czyli jak mamy np obiekt o rozmiarach 150x50 a ja stworze takich obiektów 3 i to wszystkie w QGroupBox jako QHboxLayout no to okno powinno mieć ~(3*150)H i ~50V. A działo się tak, że nowo powstałe okno było tak małe, że zakrywało wszystkie elementy, ale widoczne były przyciski ZAPISZ i ANULUJ (o tym zapomniałem napisać) stworzone w klasie tego okna. Być może wynika z tego to, że QPushButton ja i inne obiekty, które są już zdefiniowane w qt posiadają włączoną jakąś opcje, która powoduje, że rozmiar okna się dopasowuje do nich jeśli tylko są w jakimś layout.

0

Bardzo dziwne jest to co piszesz. Napisałem sobie taką kalsę próbę:

class MyDialog : public QDialog
{
    Q_OBJECT

    QBoxLayout *layout;

public:
    explicit MyDialog(QWidget *parent = 0);

signals:

public slots:
    void addItem();
};

MyDialog::MyDialog(QWidget *parent) :
    QDialog(parent, Qt::Window|Qt::Dialog)
{
    layout = new QBoxLayout(QBoxLayout::TopToBottom, this);

    QPushButton *button = new QPushButton("Add next item", this);
    layout->addWidget(button);
    connect(button, SIGNAL(clicked()),
            this, SLOT(addItem()));
}

void MyDialog::addItem()
{
    QLabel *label = new QLabel(QString("Item %1").arg(layout->count()), this);
    layout->addWidget(label);
}

I rozmiar dialogu zmienia mi się automatycznie, po każdym kliknięciu przycisku, bez jakichkolwiek dodatkowych kombinacji, wiec nie rozumiem z czym masz kłopot.

0

No to ja robię to tak. Klasa MOJEGO obiektu (dwa radiobutton + label)

plik nagłówkowy:

#include <QGridLayout>
#include <QRadioButton>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QWidget>
#include <QSizePolicy>

class obiektnowegozlec : public QWidget
{
    Q_OBJECT
public:

    QRadioButton *tak , *nie;
    QLabel *trescpytan;
    QGroupBox *grupa;
    QHBoxLayout *Hbox;
    QString tresc_pyt;


    obiektnowegozlec(QString tresc_pyt, QWidget *parent=0);

    void tworzenie();


    
signals:
    
public slots:
    
};

#endif // OBIEKTNOWEGOZLEC_H

plik źródłowy.

#include "obiektnowegozlec.h"
#include "oknogl.h"

obiektnowegozlec::obiektnowegozlec(QString tresc_pyt, QWidget *parent) : QWidget(parent), tresc_pyt(tresc_pyt)
{
    tworzenie();

}

void obiektnowegozlec::tworzenie()
{
    tak = new QRadioButton("TAK" , this);
    nie = new QRadioButton("NIE" , this);
    trescpytan = new QLabel(tresc_pyt , this);
    trescpytan->setWordWrap(true);
    trescpytan->setFixedSize(150,50);
    tak->setChecked(true);

    grupa = new QGroupBox(this);
    Hbox = new QHBoxLayout;

    Hbox->addWidget(trescpytan);
    Hbox->addWidget(tak);
    Hbox->addWidget(nie);

    grupa->setLayout(Hbox);

}

I teraz stworzenie kilkunastu obiektów w klasie NoweZlecenie dziedziczącej po QDialog. Stworzenie odbywa się w funkcji, zamieszczam tutaj tylko jej ciało. W Ciele, ustalam, jaka ma być ilość obiektów. Tworzone są jako wskaźnik na tablice wskaźników. O il ilości decyduje zmienna w innej klasie. W zależności od tego czy zmienna 'of' ma wartość 1 czy inną uruchamiam odpowiednie własne makro.

void NoweZlecenie::dodanieobiektow()
{
    if(of==1)
    {

        wsk->obsql->Oper_FORMULARZ(sql::ZCZYTANIE_PYTAN_PODS);

        obiekt = new obiektnowegozlec*[wsk->obsql->zmiennatablform];
        int i;


        for(i = 0 ; i<wsk->obsql->zmiennatablform ; i++)
        {
            obiekt[i] = new obiektnowegozlec(wsk->obsql->trescpytsql[i] ,this);

        }
    }
    else
    {

        wsk->obsql->Oper_FORMULARZ(sql::ZCZYTANIE_PYTAN_ROZSZ);
        obiekt = new obiektnowegozlec*[wsk->obsql->zmiennatablform];
        int i;
        for(i = 0 ; i<wsk->obsql->zmiennatablform ; i++)
        {
            obiekt[i] = new obiektnowegozlec(wsk->obsql->trescpytsql[i], this);
        }
    }

No i tutaj wreszcie funkcja dająca wszystko do QGridLayout. Funkcja działa w zależności od warunku tworzy kolumny obiektów w tym wypadku po 5. Można to oczywiście zmienić. Jak widać ilość obiektów jest ograniczona. Proszę przyjrzyj się.

void NoweZlecenie::gridlaj()
{
    lajout = new QGridLayout(this);
    int i;
    for(i=0 ; i<wsk->obsql->zmiennatablform ; i++)
    {

        if(i<=5)
        {

            lajout->addWidget(obiekt[i], i , 0);


        }
        else if(i<=11)
        {
            lajout->addWidget(obiekt[i], i-6 , 1);

        }
        else if(i<=17)
        {
            lajout->addWidget(obiekt[i], i-12 , 2);

        }
        else if(i<=23)
        {
            lajout->addWidget(obiekt[i], i-18 , 3);

        }

    }

    lajout->addWidget(boxp,11,0); // boxp to QGroupbox + QHboxLayout są to dwa przyciski anul i zapisz to właśnie one się nie "chowały"
    this ->setLayout(lajout);

}
0

No i problem widać jak na dłoni. Twój widget obiektnowegozlec nie ma połączania layoutem z grupa (nie żadnego skojarzenia rozmiarów między tymi obiektami).
Są dwa rozwiązania:

  1. na szybkiego dodać brakujący layout (jakikolwiek)
  2. albo pozbyć się jednego piętra zależności (zbędnego) i dziedziczyć po QGroupBox a nie po QWidget (wtedy pole grupa jest zbędne).
0

Faktycznie zadziałało :) Użyłem sposobu drugiego. Odziedziczyłem po QGroupBox. Jednak z uwagi na Twoją pomoc czuję się trochę jakbym nacisnął guzik, a 1000 km dalej wyleciało coś w powietrze bez mojej świadomości :)
Mógłbyś wytłumaczyć mi ten mechanizm, dokładniej ? drugi sposób chyba łapie bardziej, a rozumiem go tak:

Tworząc obiekt w mojej własnej klasie obiektnowegozlec :
QGroupbox grupa = new QGropuBox(this)
Słówko this jest kluczowe, ponieważ wtedy tworze obiekt jakby w TYM widzecie w klasie obiektnowegozlec, a nie w TYM oknie QDialog, dlatego QDialog nie widzi mojego widzetu jako typowe dziecko. Jeśli odziedziczę po QGropuBox klasa stanowi całkowity obiekt, który chce umieścić w QDialog. Czy tak?

Sposób 1 tzn dodać Layout na szybko. Miałeś na myśli np stworzyć QBoxLayout w obiektnowegozlec wrzucić to wszystko do niego i wtedy stworzyć w QDialog?

ps. dziękuje bardzo za kolejną trafną radę.

0

Widget normalnie nie zarządza wielkością swoich dzieci. Jeśli zmienia się jego rozmiar nie przesuwa ani nie zmiana rozmiaru dzieci. Widget swój preferowany rozmiar zwraca za pomocą metody wirtualnej sizeHint. Domyślnie zwraca to wartość (50,50) (chyba, że masz layouta). Bez layouta, to jawny kod jest odpowiedzialny za obliczanie sizeHint oraz zarządzanie pozycją i rozmiarem dzieci
Jeśli ustawiasz layout na widget'cie to widget zrzeka się zarządzania swoimi dziećmi na rzecz layout-a. Widget zwraca sizeHint obliczny przez layout i to layout ustawia pozycję i rozmiar dzieci.
Layout to po prostu gotowy kawałek kodu,który wykonuje obliczanie związane z pozyją i rozmiarem.

Jeśli twój widget nie ma layouta, to nie zwraca właściwego sizeHint, w wyniku czego, właściwa wielkość nie propaguje się do niższych warstw aż do samego okna i dlatego okno ostatecznie przybrało niewłaściwy rozmiar.

0

Dziękuje za pomoc. Wszystko jasne w tej kwestii. Uważam temat za wyczerpany.
Pozdrawiam

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