Widget mit eigenem Slot



  • Abend alle miteinander.
    Habe 3 Qt Bücher vor mir und komme trotzdem seit mehreren Stunden nicht mehr weiter.
    Wollte das nach dem drücken einer Taste eine selbst Def. Funktion abläuft. Jedoch klappt es einfach nicht.
    Arbeite mit Visual Studio 2005 und QT Designer.
    Es lässt sich ausführen aber leider passiert nichts… 😕 😕

    //Erstellt vom Qt Designer
    ui_open.h

    /********************************************************************************
    ** Form generated from reading ui file 'open.ui'
    **
    ** Created: Mon 4. Jul 23:33:22 2011
    **      by: Qt User Interface Compiler version 4.5.3
    **
    ** WARNING! All changes made in this file will be lost when recompiling ui file!
    ********************************************************************************/
    
    #ifndef UI_OPEN_H
    #define UI_OPEN_H
    
    #include <QtCore/QVariant>
    #include <QtGui/QAction>
    #include <QtGui/QApplication>
    #include <QtGui/QButtonGroup>
    #include <QtGui/QHeaderView>
    #include <QtGui/QLabel>
    #include <QtGui/QMainWindow>
    #include <QtGui/QMenuBar>
    #include <QtGui/QPushButton>
    #include <QtGui/QStatusBar>
    #include <QtGui/QToolBar>
    #include <QtGui/QWidget>
    
    QT_BEGIN_NAMESPACE
    
    class Ui_openClass
    {
    public:
        QWidget *centralWidget;
        QPushButton *pushButton;
        QLabel *label;
        QMenuBar *menuBar;
        QToolBar *mainToolBar;
        QStatusBar *statusBar;
    
        void setupUi(QMainWindow *openClass)
        {
            if (openClass->objectName().isEmpty())
                openClass->setObjectName(QString::fromUtf8("openClass"));
            openClass->resize(600, 400);
            centralWidget = new QWidget(openClass);
            centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
            pushButton = new QPushButton(centralWidget);
            pushButton->setObjectName(QString::fromUtf8("pushButton"));
            pushButton->setGeometry(QRect(180, 160, 75, 23));
            label = new QLabel(centralWidget);
            label->setObjectName(QString::fromUtf8("label"));
            label->setGeometry(QRect(190, 80, 46, 14));
            openClass->setCentralWidget(centralWidget);
            menuBar = new QMenuBar(openClass);
            menuBar->setObjectName(QString::fromUtf8("menuBar"));
            menuBar->setGeometry(QRect(0, 0, 600, 22));
            openClass->setMenuBar(menuBar);
            mainToolBar = new QToolBar(openClass);
            mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
            openClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
            statusBar = new QStatusBar(openClass);
            statusBar->setObjectName(QString::fromUtf8("statusBar"));
            openClass->setStatusBar(statusBar);
    
            retranslateUi(openClass);
    
            QMetaObject::connectSlotsByName(openClass);
        } // setupUi
    
        void retranslateUi(QMainWindow *openClass)
        {
            openClass->setWindowTitle(QApplication::translate("openClass", "open", 0, QApplication::UnicodeUTF8));
            pushButton->setText(QApplication::translate("openClass", "PushButton", 0, QApplication::UnicodeUTF8));
            label->setText(QApplication::translate("openClass", "TextLabel", 0, QApplication::UnicodeUTF8));
            Q_UNUSED(openClass);
        } // retranslateUi
    
    };
    
    namespace Ui {
        class openClass: public Ui_openClass {};
    } // namespace Ui
    
    QT_END_NAMESPACE
    
    #endif // UI_OPEN_H
    

    //open.h

    #ifndef OPEN_H
    #define OPEN_H
    
    #include <QtGui/QMainWindow>
    #include "ui_open.h"
    
    class MyClass : public QWidget  
    {
    Q_OBJECT
    Ui_openClass ee;
    public:
    MyClass();
    int value() const {return val; }
    
    private slots:
    		void eigenfunktion()
    		{
    		ee.label->clear();
    		}
    
    private:
    		int val;
    
    };
    
    class open : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	open(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~open();
    
    private:
    	Ui::openClass ui;
    };
    
    #endif // OPEN_H
    

    /main

    #include "open.h"
    #include <QtGui/QApplication>
    
    int main(int argc, char *argv[])
    {
    	QApplication a(argc, argv);
    	open w;
    	w.show();
    	return a.exec();
    }
    

    / open.cpp

    #include "open.h"
    
    open::open(QWidget *parent, Qt::WFlags flags)
    	: QMainWindow(parent, flags)
    {
      Ui_openClass bb;
      connect( bb.pushButton, SIGNAL( clicked() ), this, SLOT( MyClass::eigenfunktion() ) );
      ui.setupUi(this);
    }
    
    open::~open()
    {
    
    }
    


  • Irgendwas ist bei dir durcheinander geraten...Erstmal hast du gleich 2 Klassen in einer Header->open.h Dort in deiner Hauptklasse "open" befindet sich mit Ui::openClass ui; die GUI. Bis hier ist für mich noch alles verständlich. Im Konstruktor open::open(...) umgehst du aber die Namensraumklammerung und erzeugst ein zweites mal eine GUI mit Ui_openClass bb; Dann greifst du auf dein erstes Objekt zu und startest die GUI mit ui.setup(this); Dazwischen verbindest du noch deine zweite, nicht angezeigt GUI bb... Wieso 2 GUI Objekte und dann noch das mit dem Namensraum?! Hast du da was durcheinander gebracht?

    Das einfachste ist es, Ui::openClass *ui; in Klasse "open" zu setzen, dem Konstruktor open::open(...) : QMainWindow(...), ui(new Ui::openClass) zu sagen und dann den Zeiger weiterzureichen... Dann entstehen keine Konflikte, weil es nur genau ein Zeiger ist. Außerdem erwartet connect() Zeiger, du hast mit dem Objekt bb aber keinen übergeben-> &bb wäre es... Kläre das bitte nochmal



  • Ich sehe grad in deiner eigenen Klasse erzeugst du auch noch ein drittes Mal ein GUI-Objekt...Bist du sicher, dass das so in deinen Büchern steht?



  • Vielen dank, läuft. 👍

    ja man sollte echt nicht mehr so spät Programmieren.

    Habe die meiste Zeit in C Programmiert und bin noch nicht so vertraut mit Klassen und Objekten.

    ps. open ist jetzt openneu // alles neu aufgesetzt

    main.cpp und ui_open.h bleiben gleich

    openneu.cpp

    #include "openneu.h"
    
    openneu::openneu(QWidget *parent, Qt::WFlags flags)
    	: QMainWindow(parent, flags)
    {
    	ui.setupUi(this);
    
    	connect( ui.pushButton, SIGNAL( clicked() ),this , SLOT( eigenfunktion() ) ); 
    }
    
    openneu::~openneu()
    {
    
    }
    
    openneu.h
    
    #ifndef OPENNEU_H
    #define OPENNEU_H
    
    #include <QtGui/QMainWindow>
    #include "ui_openneu.h"
    
    class openneu : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	openneu(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~openneu();
    
    private:
    	Ui::openneuClass ui;
    
    private slots:
            void eigenfunktion()
            {
            ui.label->setText("test");
            }
    
    };
    
    #endif // OPENNEU_H
    


  • Na sieht doch sehr viel übersichtlicher aus 👍



  • wollte es nun so einrichten das bestimmte Funktionen als thread ausgeführt werden.
    Leider passiert nichts wenn ich auf den zweiten Button klicke.
    Ist es auch möglich alles in eine klasse einzubauen ?

    openneu.h

    #ifndef OPENNEU_H
    #define OPENNEU_H
    
    #include <QtGui/QMainWindow>
    #include <QThread>
    #include "ui_openneu.h"
    
    class openneu : public QMainWindow 
    {
    	Q_OBJECT
    
    public:
    	openneu(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~openneu();
    
    private:
    	Ui::openneuClass ui;
    
    private slots:
    
            void eigenfunktion()
            {
            ui.label->setText("test");
            }
    
    };
    
    class Thread: public QThread
    {
    	Q_OBJECT
    
    public:
    	Thread();
    	void setMessage(const QString &message);
    	void stop();
    
    private slots:
    
    	void see()
    	{
    		graf.label->setText("Thread geht");
    	}
    
    private:
    	Ui::openneuClass graf;
    	QString messageStr;
    	volatile bool stopped;
    };
    
    #endif // OPENNEU_H
    

    openneu.cpp

    #include "openneu.h"
    
    openneu::openneu(QWidget *parent, Qt::WFlags flags)
    	: QMainWindow(parent, flags)
    {
    	ui.setupUi(this);
    	connect( ui.pushButton, SIGNAL( clicked() ),this , SLOT( eigenfunktion() ) ); 
    
    }
    
    Thread::Thread()
    {
    connect( graf.pushButton_2, SIGNAL( clicked() ),this , SLOT( see() ) ); 
    }
    
    openneu::~openneu()
    {
    
    }
    


  • ich habe nochmal versucht das ganze anders aufzubauen. Leider bekomme ich diesen Fehler nicht weg:

    error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'thread1'
    error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.

    ich bin für jede Hilfe sehr dankbar.

    openneu.h

    #ifndef OPENNEU_H
    #define OPENNEU_H
    
    #include <QtGui/QMainWindow>
    #include <QThread>
    #include "ui_openneu.h"
    
    class openneu : public QMainWindow 
    {
    	Q_OBJECT
    
    public:
    	openneu(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~openneu();
    
    private:
    	Ui::openneuClass ui;
    	Thread thread1;
    
    private slots:
    
            void eigenfunktion()
            {
            ui.label->setText("test");
            }
    
    };
    #endif // OPENNEU_H
    
    #ifndef THREAD_H
    #define THREAD_H
    
    class Thread: public QThread
    {
    	Q_OBJECT
    
    private:
    	Ui::openneuClass graf;
    
    public:
    	Thread();
    
    		void startthread1()
    		{
    	    graf.label->setText("thread");
    		}
    
    protected:
    	//void run();
    };
    
    #endif
    

    openneu.cpp

    #include "openneu.h"
    
    openneu::openneu(QWidget *parent, Qt::WFlags flags)
    	: QMainWindow(parent, flags)
    {
    	ui.setupUi(this);
    	connect( ui.pushButton, SIGNAL( clicked() ),this , SLOT( eigenfunktion() ) ); 
    
    }
    
    openneu::~openneu()
    {
    
    }
    
    Thread::Thread()
    {
    		connect( graf.pushButton, SIGNAL( clicked() ),this , SLOT(thread1.startthread1() ) );
    }
    


  • In deinem openneu.h musst du <thread.h> nicht <QThread.h> reinziehen.



  • bist du dir sicher ? weil in thread.h kommt doch eigentlich nur die Definition der Thread Klasse. Diese ist bei mir aber doch schon in openneu.h drin.



  • Ehm ich glaube hier liegt erneut ein Fehler vor...Hast du dir schonmal die Doku angesehen von QThread? Ableiten in eine Unterklasse ist schon richtig, aber du musst die virtuelle Funktion run() überschreiben und dann für das QThreadObjekt start() aufrufen. Holzeimer hat Quatsch erzählt!



  • Und um mich nochmal zu wiederholen, die Erzeugung zweier unabhängig voneinander existierender GUI-Objekte in zwei verschiedenen Klassen ist gewollt?!

    btw du hast due run()-Funktion bereits da, nur auskomentiert....



  • BootLag-BootLag- schrieb:

    Holzeimer hat Quatsch erzählt!

    Ich bin davon ausgegangen das die Thread-Klasse in einem eigenen Headerfile thread.h ist. Willst du das in einem File musst du die Klasse Thread vor der Klasse openneu deklarieren.



  • habe es versucht umzusetzen. Leider stecke ich wieder fest.

    error C2065: 'thread1': nichtdeklarierter Bezeichner
    error C2228: Links von ".isRunning" muss sich eine Klasse/Struktur/Union
    error C2228: Links von ".start" muss sich eine Klasse/Struktur/Union befinden.

    habe ich vergessen etwas einzubinden ? lg

    thread.cpp

    #include <QtGui>
    #include "thread.h"
    
    Thread::Thread() {
    Thread thread1;
    }
    
    void Thread::run() {
    	//Hier findet die eigentliche Arbeit statt 
    	  ui.label->setText("Thread wurde gestartet");
    }
    

    thread.h

    //thread.h
    #ifndef THREAD_H
    #define THREAD_H
    #include <QThread>
    
    class Thread : public QThread {
       Q_OBJECT
    public:
       Thread();
    protected:
       void run();
    
    };
    #endif
    

    openneu.h

    #ifndef OPENNEU_H
    #define OPENNEU_H
    
    #include <QtGui/QMainWindow>
    #include <QDialog>
    #include <QTextEdit>
    #include "thread.h"
    #include "ui_openneu.h"
    
    class openneu : public QMainWindow 
    {
    	Q_OBJECT
    
    public:
    	openneu(QWidget *parent = 0, Qt::WFlags flags = 0);
    	~openneu();
    
    private:
    	Ui::openneuClass ui;
    	Thread thread1;
    
    private slots:
    	void threadlauft();
    	void threadReady();
    	void startThread1();
    
            void eigenfunktion()
            {
            ui.label->setText("test");
            }
    
    };
    #endif // OPENNEU_H
    

    openneu.cpp

    #include "openneu.h"
    
    openneu::openneu(QWidget *parent, Qt::WFlags flags)
    	: QMainWindow(parent, flags)
    {
    
    	ui.setupUi(this);
    	connect( ui.pushButton, SIGNAL( clicked() ),this , SLOT( eigenfunktion() ) ); 
    	connect( ui.pushButton_2, SIGNAL( clicked() ),this , SLOT( startThread1() ) ); 
    }
    
    openneu::~openneu()
    {
    
    }
    
    void openneu::threadlauft() {
    		ui.label->setText("Thread läuft schon");
    	}
    
    void openneu::threadReady() {
    		ui.label->setText("Thread ist fertig");
    	}
    
    /*
    void openneu::startThread1()
    {
    		if(thread1.isRunning()) {
    		threadlauft();
    		connect(&thread1, SIGNAL(finished()),
    			this, SLOT( threadReady())); }
    
    		else {
    			thread1.start(); } 
    }
    */
    

    main.cpp

    #include "openneu.h"
    #include <QtGui/QApplication>
    
    int main(int argc, char *argv[])
    {
    	QApplication a(argc, argv);
    	openneu w;
    	w.show();
    	return a.exec();
    }
    


  • bin schon seit zwei Tagen dran. Ich packe es einfach nicht das openneu das Objekt von Thread sieht.
    😕 😕 😞 😞



  • Grundlegend falsch ist

    Thread::Thread() {
    Thread thread1;
    }
    

    Dabei erzeugt eine Thread-Instanz in ihrem Konstruktor wiederum eine Thread-Instanz. Und das endlos !!

    class Thread: public QThread
    {
    ...
        Ui::openneuClass ui;
    ...
    }
    

    Damit wird eine 2. Instanz der Ui::openneuClass erzeugt. Das macht keinen Sinn.
    Willst du im Thread auf die existierende openneuClass Instanz zugreifen, kannst du das in folgender Art verwenden. Ist zwar nicht schön, sollte aber gehen.

    class Thread: public QThread
    {
    ...
        Ui::openneuClass* ui;
        Thread(openneuClass* _ui, QObject * parent = 0 ) : QThread(parent) { ui = _ui; }
    ...
    }
    

    Mir scheint, du hast das grundlegende C++ Klassenkonzept nicht ganz verstanden 😃 . Nicht aufgeben, aller Anfang ist schwer. Es lohnt sich auf jeden Fall dran zu bleigen 👍



  • @holzeimer
    ups ich habe leider openneu.cpp als openneu.h gepostet. Ist jetzt korrigiert.
    Meiner Meinung nach mü´te ich Thread thread1 in der openneu Klasse deklarieren.

    Aber leider kommt dann der Fehler:

    error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Thread::Thread(void)" (??0Thread@@QAE@XZ)" in Funktion ""public: __thiscall openneu::openneu(class QWidget *,class QFlags<enum Qt::WindowType>)" (??0openneu@@QAE@PAVQWidget@@V?$QFlags@W4WindowType@Qt@@@@@Z)".
    fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

    deswegen habe ich versucht es in den Konstruktor einzubauen. lg



  • Du hast class Thread in thread.h thread.cpp ausgelagert?

    thread.cpp ist Teil des Projekts, so dass der Compiler thread.cpp übersetzt und anschließend beim Linken dazuhängt?

    Die Fehlermeldung deutet darauf hin, dass dies nicht so ist.



  • jap habe die Klasse Thread aufgeteilt. Denke es liegt an den include files.
    lg



  • Ha, es lebt. Ich musste nur die include Ordner im Visual Studio adden.
    Nun gut,ich kann es endlich starten.
    Lieder passiert aber für mich etwas sehr eigenartiges.

    Thread::run()
    

    erkennt

    ui.label->setText()
    

    nicht an.

    Darauf habe ich ( glaube auch nicht das es ganz richtig ist)
    In der Klasse Thread

    Ui::openneuClass ui
    

    eingefügt.
    Klicke ich nun auf den Button kommt der Fehler:

    Unbehandelte Ausnahme bei 0x6706c99c (QtCored4.dll) in openneu.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x8b01e88b.

    Und springt in die Zeile:
    inline int size() const { return d->size; } aus der qstring.h Datei.
    Mit der Aufrufliste
    QtCored4.dll!QString::size() Zeile 104 + 0xc Bytes C++

    Bin wieder ratlos und für jede Hilfe oder Tipp dankbar.
    lg

    Edit: Wenn ich system("cmd") in run() einbaue läuft alles wie es soll. ( sehr geil). Was mache ich also mit dem label falsch. hmmmmmm



  • Problem ist

    openneu.h

    class openneu : public QMainWindow
    {
    ...
    private: <-------
        Ui::openneuClass ui;
    

    Somit ist ui von außen nicht zugänglich.

    Ich würde es so machen.

    class openneu : public QMainWindow
    {
    ...
    private:
        Ui::openneuClass ui;
    public:
        void setLabel(const QString& label);
    
    void openneu::setLabel(const QString& label)
    {
    	ui->label->setText(label);
    }
    
    #include "openneu.h"
    class Thread: public QThread
    {
        openneu* ui;
        Thread(openneu* _ui, QObject * parent = 0 ) : QThread(parent) { ui = _ui; }
    } 
    
    ...
    ui->setLabel()
    

Anmelden zum Antworten