Generowanie okienka gdy wcisnę przycisk Qt

0

Witam.

Chcę gdy użytkownik kliknie przycisk to żeby wygenerowało się okienko. Udało mi się napisać tyle że jak kliknę przycisk to okienko pojawia się na sekundę i znika. I nie wiem jak to rozwiązać.

Dziękuje za każdą odpowiedź i życzę miłego dnia.

1

To pokaż ten kod.

Być może obiekt okienka deklarujesz w jakiejś metodzie zamiast globalnie i okienko pojawia się na chwile ale gdy kod wychodzi z bloku metody obiekt jest niszczony a tym samym i okienko.

Wybacz ale w ciemno nie zgadnę jaki jest problem bez kodu.

0
pestka12 napisał(a):

Witam.

Chcę gdy użytkownik kliknie przycisk to żeby wygenerowało się okienko. Udało mi się napisać tyle że jak kliknę przycisk to okienko pojawia się na sekundę i znika. I nie wiem jak to rozwiązać.

Dziękuje za każdą odpowiedź i życzę miłego dnia.

To brzmi jakbyś tworzył instancję QWidget/QMainWindow lokalnie na stosie, która za moment jest ubijania po wyjściu z zakresu ważności. Ale, bez kodu jaki stworzyłeś to nie pomożemy.

0

Pamiętaj o odpowiednim przydzieleniu rodzica i podłączeniu sygnału. Dla okna samodzielnego wskaźnik na rodzica to nullptr. Trzeba wtedy dbać po jego prawidłową destrukcję. Tu poglądowo bez odpowiedzi na pytania "co jak będzie więcej okien, czy można bez new, jak to zrobić lepiej...":

#include <QApplication>
#include <QWidget>
#include <QPushButton>

class Widget : public QWidget
{
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
private:
    void createWidget();
    QPushButton * myButton;
    QWidget * newWidget;
};

Widget::Widget(QWidget *parent)
    : QWidget{parent},
      myButton{new QPushButton("Create", this)},
      newWidget{nullptr}
{
    // Połączenie przycisk->kreowanie nowego okna
    connect(myButton, &QPushButton::clicked, this, &Widget::createWidget);
}

void Widget::createWidget() {
    // Nowe samodzielne okno nie posiada wskaźnika na rodzica.
    newWidget = new QWidget(nullptr);
    newWidget->show();
}

Widget::~Widget() {
    delete newWidget;
}


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Widget w;
    w.show();

    return QApplication::exec();
}

0

Kilka uwag:

  1. (linia 41) zamień return QApplication::exec(); na return app.exec();
  2. (linia 12) masz ten przycisk, tworzysz go na liście inicjalizującej konstruktora, później podpinasz slot w connect ale, gdzie go dodajesz do twojego pierwotnego widgetu?
  3. (linia 22) powinno być raczej connect(myButton, SIGNAL(clicked), this, SLOT(createWidget));
  4. (linia 5) twoja klasa jako że dodajesz własny slot powinna mieć makro Q_OBJECT
  5. (linia 25) skoro jest to metoda slotu to powinna mieć adnotację public slots:
  6. Ogólna uwaga: jeśli tworzysz nowe okienko to raczej powinno być to QMainWindow, QDialog. QWidget nie specjalnie się do tego nadaje ale pewnie nie jest to główny błąd opisanego problemu.
1

1.) QApplication::exec() to funkcja statyczna, więc bez różnicy
2.) Hmm... przecież jest dodany przez podanie mu this?
3.) To co proponujesz to jest stara składnia connect
5.) Słowa signals/slots nie są obowiązkowe. No i nic nie stoi na przeszkodzie żeby sygnały czy sloty były prywatne/chronione

4.) i 6.) zgoda

1
tajny_agent napisał(a):

4.) i 6.) zgoda

  1. Zbędne jest stosowanie Q_OBJECT jeśli connect jest w stylu Qt 5.*. Nie potrzebuję tu metaklas więc po co? Stare połączenie z makrami SIGNAL() SLOT(), jest niezbędne jeśli mam chęć posiadania polimorfizmu i generuje problem (jeśli nie ma połączenia) w runtime. Lepiej mieć błąd ( szczególnie w tak prostej aplikacji) na etapie kompilacji. Tak więc zamierzone.

  2. Także zbędna zabawa z innymi obiektami niż QWidget bo problem dotyczy "parentingu" i połączenia slot-sygnał.

0
ReallyGrid napisał(a):

Kilka uwag:
...
2. (linia 12) masz ten przycisk, tworzysz go na liście inicjalizującej konstruktora, później podpinasz slot w connect ale, gdzie go dodajesz do twojego pierwotnego widgetu?
...
5. (linia 25) skoro jest to metoda slotu to powinna mieć adnotację public slots:
...

Na część odpowiedziałem już w poście kolegi.
2) To ma być okno bez rodzica bo jest samodzielne. W obiektach dziedziczących z widgetów Qt, nastąpiło by osadzenie w obrębie okna rodzica. Stąd zamierzone zaznaczenie faktu braku rodzica (słowo klucz okna niemodalne)
5) Jak wyżej, połączenie jest w stylu Qt 5., stąd nie jest wymagane obsługiwanie meta-klas ani innych elementów. Ergo, zbędny Q_OBJECT. Od Qt 5. do połączenia możesz podać nawet lambdę.

PS. Jak napisałem, w tym małym programie, nie implementowałem już rozróżniania okien bo może być ich kreowanych wiele ani łączenia zamknięcia okna wyskakującego do slotu okna kreującego. Problem o który pytał kolega wynikał z nieprawidłowego przydzielania rodzica który w tym przypadku powinien mieć wskaźnik nullptr oraz ew. przyłączenia sygnału kreującego. Poza tym tak konstrukcja połączenia sygnału (o ile jest możliwa a tu owszem), w sposób istotny ogranicza pracę metaklasy (z makrem Q_OBJECT) która dodaje narzut przy wywołaniu sygnału (przeszukanie sygnałów i wyłuskiwanie wskaźników na metody).

0

Pewnie okienko ci znika bo w metodzie klasy tworzysz zmienną lokalną zamiast posługiwać się wskaźnikiem jako składowej klasy

0

U mnie działa i nic nie znika po sekundzie ale zrobiłem to w stylu Qt4. Kod poniżej:
main.cpp:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    return a.exec();
}

mainwindow.h:

#ifndef KKK11_MAINWINDOW_H
#define KKK11_MAINWINDOW_H

#include <QWidget>
#include <QPushButton>

class MainWindow: public QWidget {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr):
            QWidget(parent),
            createWidget(new QPushButton("Create widget", this)) {
        connect(createWidget, SIGNAL(clicked()), this, SLOT(makeWidget()));
    }
    
    ~MainWindow() {
        delete anotherWidget;
    }

private slots:
    void makeWidget() {
        anotherWidget = new QWidget;
        anotherWidget->show();
    }

private:
    QPushButton* createWidget;
    
    QWidget* anotherWidget;
};

#endif // KKK11_MAINWINDOW_H
0

Bardzo dziękuje za każdą odpowiedź ale zapomniałem edytować i napisać że już rozwiązałem ten problem.
Ale mam problem z QLine ponieważ nie wiem jak to wyświetlić w aplikacji.

Jeszcze raz dziękuje za każdą odpowiedź i życzę miłego dnia.

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