Qt dialogablakból mainwindow függvényének elérése.

 ( zolti | 2010. március 31., szerda - 22:39 )

Sehogy sem tudom elérni a QDialogból a mainwindow függvényeit.
Így hoztam létre a dialógus ablakot:

userLogin *dialog = new userLogin(this);
if(dialog->exec()){...

A dialóg cpp fájljából próbálkoztam a parent és a parentWidget segítségével elérni mainmindow függvényét, de nem sikerült.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

QApplication::topLevelWidgets() ?

A mainwindow elérendő függvénye publikus?
A userLogin konstruktorában nem felejtetted el meghívni a bázisosztály konstruktorát a megfelelő parent paraméterrel?

Nekem elsőre _jack_ gondolata tűnik a legvalószínűbbnek.

  userLogin *dialog = new userLogin(this);

Ezt gondolom ("this" miatt) a MainWindow class valamelyik metódusában hívtad.

Az userLogin egy QDialog leszármazott.
A QDialog konstruktora:

  QDialog  ( QWidget * parent = 0, Qt::WindowFlags f = 0 )

valami ilyesmi a Te kódod:

userlogin.h:
-------------

class userLogin : public QDialog
{
  Q_OBJECT
  public:
  userLogin(QWidget *parent = 0);

  private:
  QWidget * parentWin = 0;

  [...]
};

userlogin.cpp:
---------------

#include "userlogin.h"

userLogin::userLogin(QWidget *parent) : QDialog(parent)
{
  this->parentWin = parent;
  [...]
};

@zolih: ha a [code] BBCode jelölőt használod, megmarad a kód formázása, és sokkal áttekinthetőbb lesz. (Úgy tűnik, a <code> tag viszont nem erre való). Azért nem neked válaszoltam, hogy javíthasd, ha gondolod.

kösz! valóban "nézhetőbb" :)

A <code> is erre való, de mindkettő bugos, csak máshogy. Nagyon kell figyelni a < meg [ jelekkel...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

A parent() QObjectet ad vissza, azt szerintem castolnod kell qobject_cast segítségével QMainWindow-ra, hogy elérd az alapfüggvényeit.

Ezzel megy:

foreach (QWidget *win, QApplication::topLevelWidgets()) {
    if (MainWindow *mainWin = qobject_cast(win)){
        mainWin->publicfuggveny();
    }
}

Egyébként a "C++ GUI Programming with Qt 4" könyvben is ezt használják. Nem tetszik de így legalább működik.

És ha egy _nem_ topLevel (van valami parentje) dialog ablakból nyitsz egy másikat, abból egy harmadik ablakot, és pl minden ablakból a saját közvetlen parent ablakát szeretnéd elérni ?

Ez szerintem felesleges. Ha biztos hogy a MainWindow a szülője a dialógusodnak, akkor a dialógusban:

MainWindow *mainWin = qobject_cast(this->parent())

Elég kell hogy legyen. Ha a dialógus viszont nem csak a MainWindowban jöhet létre, akkor jöhet a fenti trükközés.

Végül ez lett belőle:
if(MainWindow *mainWin = qobject_cast<MainWindow *>(this->parent())){
...
}

Úgy látom, hogy <code> vagy <code> tag-en belül sem használhatunk büntetlenül pl ilyen elemeket "<MainWindow *>" mert a drupal kiszedi.

A fenti helyesnek irt kódomnál ezt akartam írtam, de csak most látom, hogy hiányos:

foreach (QWidget *win, QApplication::topLevelWidgets()) {
    if (MainWindow *mainWin = qobject_cast<MainWindow *>(win)){
        mainWin->publicfuggveny();
    }
}

zolih fenti kódjával is próbálkoztam , de lehet, hogy ez a code bug miatt nem jó az sem (nekem nem sikerült működésre bírnom).

Csak otlet, de akar at is adhatnad pointerkent a mainwindow-t a konstruktornak. Persze, ekkor kellene egy kozos interfesz, amire csak az van kipublikalva a fo ablakbol, ami a tobbi ablak szamara is publikus.
Szerk: hulyeseget irtam, viszont kerdes: Mi van akkor, ha a konstruktor QMainWindow pointert kap, az elvben egy QObject is, es akkor a kodban nem kell castolni? Azert vagyok bizonytalan, mert az oroklodes resze mindig is zavaros volt egy picit a C++-nak, foleg, hogy napi szinten nem hasznalom.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

???

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Jó, hogy QWidget az átadott pointer, mert így a dialogus objektumodnak bármely más Wideget is lehet a szülője. Ráadásul tök kényelmesen tudod cast-olni, ha szükség van rá. Nem kell ennyire tartani a cast-olástól. Sok esetben csak a compilernek mondod meg, hogy pontosan ismered az érkező pointer típusát (static_cast), futási időben ez nem jár hátránnyal. A dynamic_cast igen, de általában a könyvtárak gyorsabb cast függvényeket implementálnak.
--
http://www.naszta.hu

A túl gyakran használt castolás (a float-int típusú konverziókat és az alacsony szintű mutató bohóckodást nem számítva) legtöbbször hibás OO tervezésre utal.

Másképp fogalmazva: a qobject_cast<MyWidget*>(mySubWidget->parent())->foo(); nem csak kényelmetlen, átláthatatlan és karbantarthatatlan, de alapvetően rossz megoldás is.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

hasznalj singletont