Qt (Zugriff auf UI)
-
Hallo,
ich entwickel mit dem Qt-Creator unter Windows einen kleines Testprogramm und habe auf meiner Oberfläche einen einfachen push-button, der bei einem Klick eine Messagebox öffnen soll.Dieses Verhalten wird in der Klasse Dialog implementiert, die von MainWindow abgeleitet wird (habe als Projekt im Qt-Creator Qt4 GUI Application gewählt).
Dies funktioniert aber nicht. Folgende Fehlermeldungen erhalte ich:
error: invalid use of undefined typestruct Ui::MainWindow' in dialog.cpp (5) error: forward declaration of
struct Ui::MainWindow' in maindwindow.h (9)Quellcode von mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui/QMainWindow> #include <QMessageBox> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); protected: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; }
dialog.h:
#ifndef DIALOG_H #define DIALOG_H #include "MainWindow.h" class Dialog : public MainWindow { public: Dialog(QWidget *parent = 0); private: void doSomething(); private slots: void slot_button(); }; #endif // DIALOG_H
dialog.cpp:
#include "dialog.h" Dialog::Dialog(QWidget *parent) : MainWindow(parent) { connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot_button())); } void Dialog::doSomething() { QMessageBox *qm; qm = new QMessageBox(QMessageBox::Warning,"Warning","!!!!",QMessageBox::Ok,this); qm->exec(); } void Dialog::slot_button() { doSomething(); }
Woran liegt das?
Noch eine kurze Frage:
In Qt wird ja zwischen Präsentations-, Dialog- und Anwendungsschicht unterschieden! Stimmt bei meinem Testprogramm dann diese Aufteilung? Als Präsentationsschicht sehe ich bei mir das UI, indem ich die jeweiligen Elemente "draufziehe" und sie nicht im Quellcode einbinde.
Anwendungsschicht ist bis jetzt noch keine vorhanden.Grüße Stefan
-
Ui::MainWindow ist in dialog.cpp einfach nicht bekannt! Entweder überall, wo du das ui im Code verwenden willst ein "#include ui_mainwindow.h", was Käse ist, oder eben gleich in mainwindow.h statt der forward-declaration ein #include.
Ich persönlich finde das ui als pointer nicht so schön, da du bei jedem Zugriff unnötig erst den pointer dereferenzieren musst. Ist nicht so schlimm, aber wenn es auch ohne geht...
Im übrigen fehlt dir noch ein "Q_OBJECT" in "class Dialog". Für was du die noch extra brauchst versteh ich ehrlich gesagt nicht... Mach den SLOT doch in MainWindow.
-
error: invalid use of undefined type `struct Ui::MainWindow' in dialog.cpp (5)
Füge die Zeile
#include "ui_mainwindow.h"
in die Datei "dialog.cpp" hinein.
Aber die Frage: wieso brauchst du 2 verschiedene Klassen(MainWindow & Dialog) für dieselbes Fenster? Ich würde dir raten, die Klasse "Dialog" komplett zu entfernen und alle UI-bezogene Funktionen in der Klasse "MainWindow" zu implementieren.
-
Ich persönlich finde das ui als pointer nicht so schön, da du bei jedem Zugriff unnötig erst den pointer dereferenzieren musst. Ist nicht so schlimm, aber wenn es auch ohne geht...
Naja wenn mans richtig macht, muß niemand sonst die ui_* inkludieren, was kompilierzeit spart. Und sich um Zeigerdereferenzierungen zu sorgen wenn man Qt benutzt wirkt merkwürdig.
-
Tyrdal schrieb:
Naja wenn mans richtig macht, muß niemand sonst die ui_* inkludieren, was kompilierzeit spart. Und sich um Zeigerdereferenzierungen zu sorgen wenn man Qt benutzt wirkt merkwürdig.
Es ist sowieso ein komischer Ansatz, ein Formular zu erstellen, welches für ein MainWindow bestimmt ist, und dieses MainWindow nochmal abzuleiten. Spezialisierung macht hier wenig Sinn, die zusätzliche Funktionalität sollte man über Funktionen implementieren, ansonten wird das Widget nicht nochmal abgeleitet sondern in einem anderen Widget verwendet. Ein Formular ist einfach kein verfeinerungswürdiges Widget (ACHTUNG meine Meinung)
QObject (und damit auch QWidget) sind nicht copy-constractable und assignable, darum macht es Sinn nur Pointer durch die Gegend zu reichen. Ich fang aber deshalb nicht an nur noch pointer zu verwenden (z.B. QString, QList, usw...), und darum mein ich mann sollte es auch nicht für das ui machen. Ist aber eh Geschmackssache ("Ich persönlich finde das ui..."
-
wie gesagt, es war lediglich ein kleines Testprogramm...
ich habe noch eine Frage bezüglich der Toolbar und möchte keinen extra Thread dafür eröffnen:
Buttons kann ich im Quelltext einfach durch folgenden Code hinzufügen:
//New newAct = new QAction(QIcon("./resources/New.png"),"&New", this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip("Create a new file"); connect(newAct, SIGNAL(triggered()), this, SLOT(slot_showWarning())); mainToolBar->addAction(newAct);
Wie kann ich dies aber direkt mit dem Qt-Designer erreichen? Ich kann ja dort kein QAction auswählen und auf die Toolbar ziehen
-
piwi133 schrieb:
Wie kann ich dies aber direkt mit dem Qt-Designer erreichen? Ich kann ja dort kein QAction auswählen und auf die Toolbar ziehen
MainWindow aus Vorlage erstellen, im Formular (oder im Object Inspector auf "MainWindow") einen Rechtsklick -> add ToolBar.
Unten im Action Editor eine beliebige Action hinzufügen. Diese kann jetzt entweder ins Menu (wenn du schon ein mainMenuItem hast) oder darunter in die Toolbar gezogen werden (aus dem action editor heraus).