Meine erste eigene Klasse

Du bist neu in der Welt von C++? Dann schau hier herein!
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Meine erste eigene Klasse

Beitrag von WasserDragoon »

Hallo,
ich bin in der Welt von C++ völlig neu und muss zugeben, da ich von der Programmiersprache D komme, dass es garnicht ganz so schwer ist, wie ich es dachte.
Aer nun zu meinem Problem^^
Und zwar wollte ich, da ich ja wie viele schreibfaul bin, eine Funktion bereitstellen, womit ich einfach Menu-Items einfügen kann.
Das ganze klappt aber nicht so, wie ich es mir wünsche :-)
Denn ich bekomme folgende Fehler beim kompilieren:
mainwindow.cpp: In constructor `MyWin::MyWin(QWidget*)':
mainwindow.cpp:10: error: no matching function for call to `MyWin::addMenuItem(Q
Menu*&, const char[17], const char[5], const char[7], const char[24], void (MyWi
n::*)())'
mainwindow.h:19: note: candidates are: void MyWin::addMenuItem(QMenu*, char, cha
r, char, char, void (*)())
mainwindow.cpp: In member function `void MyWin::addMenuItem(QMenu*, char, char,
char, char, void (*)())':
mainwindow.cpp:19: error: call of overloaded `QIcon(char&)' is ambiguous
c:/Qt/4.4.1/include/QtGui/../../src/gui/image/qicon.h:72: note: candidates are:
QIcon::QIcon(QIconEngineV2*) <near match>
c:/Qt/4.4.1/include/QtGui/../../src/gui/image/qicon.h:71: note:
QIcon::QIcon(QIconEngine*) <near match>
c:/Qt/4.4.1/include/QtGui/../../src/gui/image/qicon.h:70: note:
QIcon::QIcon(const QString&) <near match>
c:/Qt/4.4.1/include/QtGui/../../src/gui/image/qicon.h:68: note:
QIcon::QIcon(const QPixmap&) <near match>
mainwindow.cpp:19: error: invalid conversion from `char' to `const char*'
mainwindow.cpp:19: error: initializing argument 1 of `static QString MyWin::tr
(const char*, const char*)'
mainwindow.cpp:20: error: invalid conversion from `char' to `const char*'
mainwindow.cpp:20: error: initializing argument 1 of `static QString MyWin::tr
(const char*, const char*)'
mainwindow.cpp:21: error: invalid conversion from `char' to `const char*'
mainwindow.cpp:21: error: initializing argument 1 of `static QString MyWin::tr
(const char*, const char*)'
NMAKE : U1077:
Stop.
NMAKE : U1077:
Stop.
Hier mal meine Dateien:

main.cpp:

Code: Alles auswählen

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

int main( int argc, char** argv )
{
	QApplication app( argc, argv );
	
	QWidget* window = new MyWin();
	window->show();
	
	return app.exec();
}
mainwindow.h:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MyWin : public QMainWindow
{
	Q_OBJECT
	
	public:
    	MyWin( QWidget* = 0 );
	
	public slots:
    	void newCon();
	
	private:
    	void addMenuItem( QMenu*, char, char, char, char, void () );
};

#endif
mainwindow.cpp:

Code: Alles auswählen

#include "mainwindow.h"
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>

MyWin::MyWin( QWidget *parent )
  : QMainWindow( parent, 0 )
{
	QMenu* connectionMenu = new QMenu( this );
	addMenuItem( connectionMenu, ":/../res/new.png", "&New", "Ctrl+N", "Create a new connection", &MyWin::newCon );
	
	menuBar()->addMenu(connectionMenu)->setText("&Connection");
	
	statusBar();
}

void MyWin::addMenuItem( QMenu* menu, char icon, char title, char shortcut, char statustip, void fn() )
{
	QAction* action = new QAction( QIcon( icon ), tr( title ), this);
	action->setShortcut( tr( shortcut ) );
	action->setStatusTip( tr( statustip ) );
	connect( action, SIGNAL( triggered() ), this, SLOT( fn() ) );
	menu->addAction( action );
}

void MyWin::newCon()
{
	QMessageBox::information( this, "action", "new connection selected" );
}
Wäre nett, wenn ihr mich darüber aufklären könntet.
Mfg,
Danny.
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

char ist ein datentyp fuer einzelne zeichen.
sprich eine char variable fasst genau ein zeichen ('a', 'b', 'x', '\n', usw. usf.).
wenn du strings uebergeben willst (und mit Qt arbeitest), benutz am besten QString.

in der main funktion kannst du das btw. so machen:

Code: Alles auswählen

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

int main( int argc, char** argv )
{
   QApplication app( argc, argv );
   
   MyWin win;
   win.show();

   QObject::connect( &app, SIGNAL( lastWindowClosed() ),
      &app, SLOT( quit() ) );
   
   return app.exec();
}
mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

Hi,
danke erstmal für die schnelle Antwort.
Nun bekomme ich aber folgende Fehler:
mainwindow.cpp: In constructor `MyWin::MyWin(QWidget*)':
mainwindow.cpp:10: error: no matching function for call to `MyWin::addMenuItem(Q
Menu*&, const char[17], const char[5], const char[7], const char[24], void (MyWi
n::*)())'
mainwindow.h:17: note: candidates are: void MyWin::addMenuItem(QMenu*, QString,
QString, QString, QString, void (*)())
mainwindow.cpp: In member function `void MyWin::addMenuItem(QMenu*, QString, QSt
ring, QString, QString, void (*)())':
mainwindow.cpp:19: error: no matching function for call to `MyWin::tr(QString&)'

mainwindow.h:8: note: candidates are: static QString MyWin::tr(const char*, cons
t char*)
mainwindow.h:8: note: static QString MyWin::tr(const char*, cons
t char*, int)
mainwindow.cpp:20: error: no matching function for call to `MyWin::tr(QString&)'

mainwindow.h:8: note: candidates are: static QString MyWin::tr(const char*, cons
t char*)
mainwindow.h:8: note: static QString MyWin::tr(const char*, cons
t char*, int)
mainwindow.cpp:21: error: no matching function for call to `MyWin::tr(QString&)'

mainwindow.h:8: note: candidates are: static QString MyWin::tr(const char*, cons
t char*)
mainwindow.h:8: note: static QString MyWin::tr(const char*, cons
t char*, int)
NMAKE : U1077:
Stop.
NMAKE : U1077:
Stop.
mfg
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

ok ich habs mal probiert, weil ich mir auch nicht sicher war, ob/wie das mit dem uebergeben von signals klappt, hab das erst eben in deinem code entdeckt.

so funktioniert es bei mir:
main.cpp -> wie oben
mainwindow.h:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
class QString;
class QKeySequence;

class MyWin : public QMainWindow
{
   Q_OBJECT
   
   public:
       MyWin( QWidget *parent = 0 );
   
   public slots:
       void newCon();
   
   private:
	void addMenuItem( QMenu *menu, QString icon, QString title, QKeySequence shortcut,
		QString statustip, const char *fn );
};

#endif
mainwindow.cpp:

Code: Alles auswählen

#include "mainwindow.h"
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>
#include <QString>
#include <QKeySequence>

MyWin::MyWin( QWidget *parent )
  : QMainWindow( parent, 0 )
{
   QMenu* connectionMenu = new QMenu( this );
   addMenuItem( connectionMenu, ":/../res/new.png", "&New", QKeySequence( "Ctrl+N" ),
	"Create a new connection", SLOT( newCon() ) );
   
   menuBar()->addMenu(connectionMenu)->setText("&Connection");
   
   statusBar();
}

void MyWin::addMenuItem( QMenu *menu, QString icon, QString title, QKeySequence shortcut,
	QString statustip, const char *fn )
{
   QAction* action = new QAction( QIcon( icon ), title, this);
   action->setShortcut( shortcut );
   action->setStatusTip( statustip );
   connect( action, SIGNAL( triggered() ), this, fn );
   menu->addAction( action );
}

void MyWin::newCon()
{
   QMessageBox::information( this, "action", "new connection selected" );
}
probiers mal, bei fragen zum code, frag. :)

ps: was man noch anstellen koennte: die addMenuItem()-methode public machen und ein argument "const char *receiver" dazu packen, sodass man von ausserhalb die MyWin klasse bequem nutzen kann, ohne menu items nur mit slots derselben klasse zu connecten ... soviel dazu, nur als hinweis.

mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

Danke, hat funktioniert...
Nur dein Tipp versteh ich nicht so ganz.
Die MyWin-Klasse benötige ich ja nur einmal, und zwar beim Hauptfenster.
Sämtliche andere Fenster sehen dann ja anders aus...
Oder hab ich da was missverstanden?

mfg
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

WasserDragoon hat geschrieben:Danke, hat funktioniert...
Nur dein Tipp versteh ich nicht so ganz.
Die MyWin-Klasse benötige ich ja nur einmal, und zwar beim Hauptfenster.
Sämtliche andere Fenster sehen dann ja anders aus...
Oder hab ich da was missverstanden?

mfg
noe, ich mein nur so als addon, feature, wie auch immer, sodass man evtl. aus ner anderen klasse dynamisch die eintraege regeln kann.
fuer ... was auch immer :D
so koennte bspw. ein plugin einen menueintrag hinzufuegen und ihn mit ner eigenen methode (slot) verknuepfen :D
tolle sache, ich weiss, auch wenn man sowas eher nicht ein sample programm einbaut ...

mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

Ich muss sagen ich sehe wesentlich mehr Vorteile in C++ nun.
Ist halt blöd, da D viel zu jung ist, da kann man weniger Hilfestellung erwarten und vorallem weniger Umfang was GUI betrifft. Die D bindings von wxWidgets (genannt wxD) habe ich nicht einrichten können, mit gtkD konnte ich mich garnicht anfreunden vom stil her und nun habe ich qt...
find ich echt klasse, nur ist D viel leichter zu verstehen...
dafür kann man aber bei c++ prahlen und der code sieht für andere noch komplizierter aus :-D

mal btw: ich bin dabei gerade ein backup von meinem zeug zu machen, da ich gehört habe google soll wine unterstützt haben bzgl. photoshop. und da möchte ich dann gerne linux installieren, wohl wieder kubuntu... nun möchte ich aber auf virtualbox o.ä. verzichten. kann ich dann irgendwie unter linux meine programme cross-compilen, also sowohl für windows und mac als auch für linux? bei gcc ginge das irgendwie, habe ich mal gehört.

mfg
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

funktionieren soll es wohl, habs aber nie hinbekommen, klappt wohl selten richtig gut afaik.
ich weiss auch nicht, wie das dann mit qt ist, der muss ja gegen die win-libs linken eigentlich fuer windows usw...
ich hab dafuer ne vm in virtualbox eingerichtet, wo win-zeugs kompiliert wird.

von wine halt ich btw. auch nicht viel, gibt doch fuer fast alles alternativen die nativ laufen und man kann schlecht erwarten, dass windows-programme (die teils nichtmal unter windows vernuenftig laufen ...) unter linux ploetzlich voll funktionieren.
ich habs mal probiert, war ne dumme idee, hab fast nichts richtig zum laufen bekommen.

mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

Also ich habe mit wine keinerlei Probleme gehabt...
Ich schau dann immer in die AppDB, such mir Lösungen und wenns nich klappt, pech gehabt. Aber Photoshop CS2 zum Beispiel funktioniert wunderbar mit Wine (selbst getestet) inzwischen wird viell. sogar CS3 wunderbar funktionieren. Früher war das so, dass man Photoshop von einer Windows-Maschine erst rüberkopieren musste inkl. Registrys, das war dann natürlich immer pfusch.
Aber inzwischen geht sogar der Installer, muss man also wie bei Windows nur installieren und aufrufen.
eine vm wollte ich eigentlich daher meiden und direkt auch für windows und mac kompilieren.
weil es is wesentlich konfortabler, auch wenns inzwischen die freeze funktion bei virtualbox gibt, was den start der maschine verdammt verschnellt...
is aber wie ich finde total unhandlich^^ kann mich damit nich anfreunden, aber is denke ich geschmackssache.
aber ich muss mir da ma mehr infos holen bzgl. cross-compiling.
falls sich erfolge zeigen kann ich mich ja melden ;-)

mfg
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

hi,
hab nun ein anderes problem: optionale parameter.
irgendwie haut das wieder nich so hin, wie ich es wollte.
Header-Datei mainwindow.h:

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MyWin : public QMainWindow
{
    Q_OBJECT
    
    public:
        MyWin( QWidget* = 0 );
    
    public slots:
        void newCon();
    
    private:
        void addMenuItem( QMenu*, QString, QString, const char*, QString = "", QKeySequence = NULL );
};

#endif
Source-Datei mainwindow.cpp:

Code: Alles auswählen

#include "mainwindow.h"
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>

MyWin::MyWin( QWidget *parent )
  : QMainWindow( parent, 0 )
{
    QMenu* connectionMenu = new QMenu( this );
    addMenuItem( connectionMenu, "&New", "Create a new connection", SLOT( newCon() ), ":/../res/new.png", QKeySequence( "Ctrl+N" ) );
    
    menuBar()->addMenu( connectionMenu )->setText( "&Connection" );
    
    statusBar();
}

void MyWin::addMenuItem( QMenu* menu, QString title, QString statustip, const char* fn, QString icon, QKeySequence shortcut )
{
    QAction* action = ( icon != "" ? new QAction( QIcon( icon ), title, this) : new QAction( title, this ) );
    action->setShortcut( shortcut );
    action->setStatusTip( statustip );
    connect( action, SIGNAL( triggered() ), this, fn );
    menu->addAction( action );
}

void MyWin::newCon()
{
    QMessageBox::information( this, "action", "new connection selected" );
}
Compiler-Ausgabe:
mainwindow.cpp: In constructor `MyWin::MyWin(QWidget*)':
mainwindow.cpp:12: warning: passing NULL used for non-pointer converting 1 of `QKeySequence::QKeySequence(int, int, int, int)'
mainwindow.cpp:31: warning: passing NULL used for non-pointer converting 1 of `QKeySequence::QKeySequence(int, int, int, int)'
mainwindow.cpp:38: warning: passing NULL used for non-pointer converting 1 of `QKeySequence::QKeySequence(int, int, int, int)'
Zum anderen wird das PNG-Bild nicht dargestellt, was ich garnicht begreifen kann...

Meine Ordnerstruktur:
Projektordner/res - hier befindet sich das PNG-Bild new.png
Projektordner/src - hier befinden sich die header- und sourcedateien
Projectordner/compile.bat - inhalt dieser datei steht unten
compile.bat:
cd src
qmake -project
qmake
nmake
cd debug
move /y *.exe ../../dB0t.exe
cd ../..
Das einzige, was die Batch-Datei also macht, ist lediglich das ganze kompilieren und die kompilierte EXE-Datei dann in den Rootdir also den Projektordner zu verschieben...

mfg
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

funktioniert nicht, weil (steht doch in der fehlermeldung auch!) QKeySequence kein zeiger ist, also nicht NULL sein kann ...

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MyWin : public QMainWindow
{
    Q_OBJECT
   
    public:
        MyWin( QWidget* = 0 );
   
    public slots:
        void newCon();
   
    private:
        void addMenuItem( QMenu*, QString, QString, const char*, QString = "", QKeySequence* = NULL );
};

#endif 

Code: Alles auswählen

#include "mainwindow.h"
#include <QAction>
#include <QMenuBar>
#include <QMessageBox>

MyWin::MyWin( QWidget *parent )
  : QMainWindow( parent, 0 )
{
    QMenu* connectionMenu = new QMenu( this );
    addMenuItem( connectionMenu, "&New", "Create a new connection", SLOT( newCon() ), ":/../res/new.png", QKeySequence( "Ctrl+N" ) );
   
    menuBar()->addMenu( connectionMenu )->setText( "&Connection" );
   
    statusBar();
}

void MyWin::addMenuItem( QMenu* menu, QString title, QString statustip, const char* fn, QString icon, QKeySequence *shortcut )
{
    QAction* action = ( icon != "" ? new QAction( QIcon( icon ), title, this) : new QAction( title, this ) );
    if( shortcut )
        action->setShortcut( shortcut );
    action->setStatusTip( statustip );
    connect( action, SIGNAL( triggered() ), this, fn );
    menu->addAction( action );
}

void MyWin::newCon()
{
    QMessageBox::information( this, "action", "new connection selected" );
}
ist ungetestet, aber so in etwa sollte das sein.

btw. ich dachte immer so vom hoeren-sagen, dass d c++ sehr aehnlich sei, aber anscheinend isses doch relativ stark vereinfacht/beschnitten/wie mans auch nennen mag ...

mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

hmm ne das klappte so nich, habs so gelöst:

Code: Alles auswählen

void addMenuItem( QMenu*, QString, QString, const char*, QString = "", QString = "" );

Code: Alles auswählen

void MyWin::addMenuItem( QMenu* menu, QString title, QString statustip, const char* fn, QString icon, QString shortcut )
Problem ist nur weiterhin, dass die Grafik nicht angezeigt wird?!

mfg
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

hast du das ding auch richtig als resource eingebunden?
http://doc.trolltech.com/4.4/resources.html

mfg,
julian
WasserDragoon
Beiträge: 11
Registriert: 27. August 2008 13:51

Beitrag von WasserDragoon »

Ich dachte, da ich QIcon verwendet habe, wird die Datei direkt in die exe gespeichert ohne in den resourcen gefunden zu werden... bei d gabs eine import() funktion... weil selbst mit qrc-datei wird das icon nicht angezeigt :-(
-=Freaky=-
Beiträge: 503
Registriert: 29. Dezember 2006 22:54
Wohnort: HL

Beitrag von -=Freaky=- »

du musst ein qrc-file erstellen und das bild entsprechend der doku drin als ressource definieren

Code: Alles auswählen

<!DOCTYPE RCC><RCC version="1.0">
     <qresource>
     <file>new.png</file>
</qresource>
</RCC>
und anschliessend im pro-file das qrc file eintragen

Code: Alles auswählen

RESOURCES += myResourceFile.qrc
dann kannst du via ":/new.png" im programm drauf zugreifen.

mfg,
julian
Antworten