[gelöst] QMainWindow hängt bei emit



  • Moin,

    ich habe in meinem Qt Projekt zwei Klassen und die main. Eine Klasse erbt von QMainWindow und die andere von QThread.

    MainWindow wird in der Main erzeugt dann wird im Konstruktor des Fensters der Thread erzeugt und auf klick auf eine Schaltfläche emittiere ich ein Signal, welches im Thread eine Aktion ausführt, die etwa 30 Sekunden dauert. Und in dieser Zeit kann ich die Oberfläche nicht bedienen.

    Kann mir jemand erklären woran das liegt? Ich war der Meinung, dass das Signal und Slot Konzept die Kommunikation zwischen Threads vereinfachen soll.

    Hier der auf's Wesentliche gekürzte Quelltext.

    #include <QtGui/QApplication>
    #include "mainwindow.h"
    
    int main(int argc, char *argv[])
    {	QApplication a(argc, argv);
    	MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QSystemTrayIcon>
    #include <QMessageBox>
    #include <QFileDialog>
    #include <QByteArray>
    
    #include "cmythread.h"
    
    namespace Ui {
        class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
    	explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    public slots:
    	void Debug(QString DebugMessage);
    
    private slots:
        void FileExport();
    
    signals:
    	void ExportWaypoints(const char *Filepath);
    
    private:
        Ui::MainWindow *ui;
    
        CMyThread *m_pMyThread;
    };
    
    #endif // MAINWINDOW_H
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    
    	m_pMyThread = new CMyThread();
    
    	connect(ui->BtnExport, SIGNAL(clicked()), this, SLOT(FileExport()));
    	connect(this, SIGNAL(ExportWaypoints(const char*)), this->m_pMyThread, SLOT(ExportWaypoints(const char*)));
    
    	connect(m_pMyThread, SIGNAL(Debug(QString)), this, SLOT(Debug(QString)));
    
    	m_pMyThread->start();
    }
    
    void MainWindow::FileExport()
    {
    	QString Filename = QFileDialog::getOpenFileName(this,
    													tr("Datei Exportieren"),
    													"c:\\",
    													tr("gpx Dateien (*.gpx)"));
    
    	if (Filename != "")
    	{
    		QByteArray TempByteArray = Filename.toLatin1();
    
    // Hier beginnt die Misere
    		emit ExportWaypoints(TempByteArray.data());
    	}
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::Debug(QString DebugMessage)
    {
    	ui->textEdit->append(DebugMessage);
    }
    
    #ifndef CMYTHTREAD_H
    #define CMYTHREAD_H
    
    #include <windows.h>
    #include <fstream>
    
    #include <QThread>
    #include <QString>
    
    class CMyThread : public QThread
    {
    
    	Q_OBJECT
    
     public:
    	CMyThread();
    	~CMyThread();
    
        bool Initialized();
    
    	void run();
    
    public slots:
    	void ExportWaypoints(const char *Filepath);
    
    signals:
    	void Debug(QString DebugMessage);
    
    private:
    	void SendFile(const char *Filepath);
    };
    
    #endif // CMYTHREAD_H
    
    #include "cmythread.h"
    
    CMyThread::CMyThread()
    {
    	return;
    }
    
    CComDevice::~CComDevice()
    {
    }
    
    void CComDevice::run()
    {
    	exec();
    }
    
    void CComDevice::SendFile(const char *Filepath)
    {
    	// DoStuff() und das dauert hier ca. 30 Sekunden
    
        emit Debug("What has been done?");
    	return;
    }
    
    void CComDevice::ExportWaypoints(const char *Filepath)
    {
    	emit Debug("Exporting");
    	// Prepare File...
    
    	SendFile(Filepath);
    }
    

    Besten Dank im Voraus.



  • Der übliche Fehler: MyThread (das Objekt) liegt im Hauptthread. Der SLOT wird damit im Kontext des Hauptthreads ausgeführt. Um die SLOTS nun im Kontext des neuen Threads laufen zu lassen, musst du diesen nach sich selbst moven 😃
    Im Thread-Konstruktor also

    this->moveToThread(this);
    

    Wobei dich dieser Beitrag brennend interessieren sollte.



  • “it seems to work when I add this” um deinen Link mal zu kommentieren 😃

    Danke.


Anmelden zum Antworten