Wpis z mikrobloga

Cześć, robię pewną aplikację w c++ z użyciem #qt i mam pomysł jak ją rozbudować, natomiast nie wiem jak zrobić pewną część tej aplikacji i czy to w ogóle możliwe, mianowicie chodzi i takie coś:

Mam login screen (main window), loguję się i po poprawnym zalogowaniu wyskakuje okienko (na razie wszystko działa) jednak nie zamykam login screenu, bo mogę zalogować kolejne konto i chcę, by pojawiło się kolejne okienko (takie samo tylko z innymi parametrami), tylko problem w tym, żeby każde z tych okienek wykonywało swoje pętle tzn żeby nie było tak że najpierw pętle wykonuje login screen, później okno 1 a na końcu okno 2, tylko żeby wszystko odbywało się w tym samym czasie. Da się to jakoś zrobić w miarę łatwy sposób? Dodam, że próbowałem coś robić z tymi timerami w QT ale nie za bardzo to wychodziło.

Przepraszam, że wołam ale to w końcu trochę #programowanie a może ktoś robił coś podobnego.
  • 40
@morsisko: No i - co to znaczy dużo? 20? 50? Google Chrome otwiera kilkanaście czy więcej wątków na każdą kartę, to ci może dać pewne pojęcie na temat tego, jak tanie są wątki które nic nie robią :)
@frax: Tylko że właśnie tam nie ma czasochłonnych zadań, tylko program wymaga tego żeby było to wszystko wykonywane dość szybko, dodatkowo w tym main window będzie tylko taki "menedżer" czyli on praktycznie będzie tylko otwierał nowe okna i przekazywał przy ich wywołaniu nazwę procesu innej aplikacji. Co do ilości okien to zależy to od użytkownika - prawdopodobnie często będzie to tylko jedno okno, no ale czasami też i 10. Co do
@morsisko: To zależy, co w tych wątkach chcesz robić. Piszesz o jakichś pętlach, które się mogą długo wykonywać. Możliwe, że najprościej jest dla każdej takiej pętli tworzyć nowy wątek, i w ogóle tego nie wiązać z oknami. Nie wiem, co te pętle robią, i ile ich jest, tak naprawdę od tego wszystko zależy. W każdym razie - wydajnością się raczej nie przejmuj, przynajmniej dopóki nie przekroczysz, ja wiem, 100 wątków otwartych
@frax:
Ogólnie taki jest zarys:
Uruchamiamy program, pojawia się menedżer z listą procesów do wyboru, wybieramy proces z listboxa kilkamy start i do tego nowo otwartego GUI jest przesyłany PID procesu, w nowym oknie jest wypisanych kilka danych z tego procesu + opcje do wyboru, (menedżer wciąż jest otwarty) no i w tym oknie mamy coś takiego:

void function()
{
functionA();

functionB();

functionC();

}

Każda z tych funkcji zawiera jakieś tam
@morsisko: Możesz użyć timera, nic się nie wywali - kolejne uruchomienia są odpalane z pętli obsługi zdarzeń, więc dopóki nie wrócisz do niej z jednego wywołania, następne się nie zacznie. Pytanie, jak długo trwa jedno uruchomienie - czy możesz sobie pozwolić na taką przerwę w głównym wątku? Jeżeli tak, to wątki nie są ci potrzebne. Jeżeli nie, to potrzebujesz dodatkowych wątków, ale być może wystarczy ci jeden. W obu przypadkach warto
@frax: No tak, ale jak otwieram nowe okno to tak jakbym tworzył obiekt klasy(?), czyli ta funkcja function() nie jest tak jakby globalna więc chyba to kolejkowanie zbyt wiele nie da, ale wciąż muszę to przetestować, bo być może okaże się, że te odstępy pomiędzy wykonywaniem pętli kolejnych okien są bardzo małe, ale wtedy znowu prawdopodobnie nie będzie można korzystać z GUI, bo program ciągle będzie w jakiejś pętli. :(
@frax: Przepraszam, że przeszkadzam ale mam jeszcze jedno pytanie, bo widziałem, że trochę znasz się na tym QT :P
Chodzi mi o to: w mainwindow.h mam:

CoreWindow *newwindow; // wskaznik do nowego okna

i w mainwindow.cpp mam:
newwindow = new CoreWindow();
newwindow->show();

I to działa super, tylko teraz w tej klasie CoreWindow tworze obiekty innych klas i teraz już nie wiem: tworzyć je jako wskaźniki czy normalnie? coś w stylu Game
@morsisko: Zdecydowaną większość obiektów związanych z Qt (w każdym razie z Qt-owym GUI) tworzy się na stercie (przez new) i używa przez wskaźniki, chociaż czasem można je trzymać bezpośrednio. Wyjątkiem są te klasy, które używają jakiegoś współdzielenia, i ich obiekty bezpośrednio trzymają tylko wskaźnik do zawartości (d-pointer), np. QPixmap, QSettings - te zwykle trzyma się bezpośrednio.

Każdy QObject ma wskaźnik do rodzica (też QObjectu), przypisany przy tworzeniu. Jeżeli
@frax: Tak wiem, chodziło mi o własne klasy, ale chyba gdy usunę to "newwindow" to wszystko co utworzyłem w tym obiekcie też zostanie usunięte(tak mi się wydaję z punktu logiki). Chodzi mi o takie coś, że gdy wywołam sobie 10 tych okien to przy zamykaniu mam zapewne wywołać
del newwindow;
tylko jak komputer ma się domyślić co usunąć, skoro tych okien jest 10, chyba że ja coś źle zrobiłem i tak
@morsisko: newwindow to konkretny wskaźnik na konkretne okno, więc delete newwindow zniszczy i zwolni ten konkretny obiekt.

Aha, jeszcze jedna ważna sprawa - QObjectów generalnie nie należy usuwać przez delete, tylko przez QObject::deleteLater() (to jest slot, można go do czegoś podpiąć).

Jeżeli masz jakieś zarządzanie tymi oknami, to pewnie wskaźniki do nich chcesz trzymać w jakimś vectorze czy czymś takim, ewentualnie mapie. Ale możliwe, że w ogóle tego nie potrzebujesz,
@frax: Hmm, no vectorów nie wam mam po prostu taki kod podpięty pod przycisk, beż żadnych tablic

newwindow = new CoreWindow();
newwindow->show();

Czyli wystarczy, że podepnę załóżmy pod kontrolkę "X" na oknie to:
this.deleteLater();

I mam zniszczone to okno razem z wszystkimi obiektami w nim utworzonymi? Bo aktualnie sprawdzałem na zużycie RAM przez program i przy otwieraniu nowych okien zużycie się zwiększa, a przy zamykaniu nic się nie dzieję, choć nie
Czyli wystarczy, że podepnę załóżmy pod kontrolkę "X" na oknie to:

this.deleteLater();


@morsisko: Tak, oczywiście o ile this będzie tym oknem. Nie wiem, czego używasz do wiązania sygnałów ze slotami czy może robisz to ręcznie. Jeżeli tworzysz okno w QtCreatorze, i jakieś kontrolce podpinasz slot pod sygnał, to domyślnie tworzony jest slot właśnie w oknie, czyli tak jak trzeba. W innych IDE pewnie jest podobnie, ale głowy za to nie dam.
@frax: Hmm co nieco ze wskaźnikami robiłem, tylko podstawowe rzeczy ale takie są mi teraz potrzebne. Problem jest z tym że trochę inaczej to działa w QT (w takim sensie że trzeba wiedzieć kiedy to usunąć) zrobiłem sobie mały test, drugie okno miało co pięć sekund miało wyświetlać msgboxa jednak po zamknięciu okna msgbox nadal się pojawia :/
this->deleteLater(); umieściłem w destruktorze okna. Co prawda za wyświetlanie tych msgboxów odpowiedzialna jest
@morsisko: Ale deleteLater() w destruktorze nie ma sensu! deleteLater() właśnie zajmuje się wywołaniem destruktora (tylko z możliwym jakimś tam opóźnieniem).

Zamknięcie okna (krzyżykiem) nie powoduje usunięcia obiektu okna, powoduje tylko, że okno jest ukryte. Możesz je z powrotem pokazać przez show().
@frax: Trochę pokombinowałem i znalazłem chyba lepszy sposób, choć nie wiem czy do końca "poprawny", mianowicie ustawiam atrybut okna, teraz cały kod wywołujący nowe GUI wygląda tak:

newwindow = new CoreWindow();
newwindow->set_propeties(process_ID[ui->process_list->currentRow()], process_HWND[ui->process_list->currentRow()]);
newwindow->setAttribute(Qt::WA_DeleteOnClose);
newwindow->show();

Po zamknięciu msgboxy już się nie wyświetlają i zużycie RAM również spada.
Dzięki za całą pomoc. :)