Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSignal and another Form SOLVED



  • Dear Community,

    I know that another thread can't change widgets so I made Q_SIGNALS for these purpose. In the Main Window it works fine.
    For value retrieved by the executed Funtion I am using std::promise and std::future and it waits until the value appeared.

    Now I have a TCP FileTransfer inside it which shall open another Window which displays Transfer Progress. Now creation of the window and opening works fine too. The std::promise is also retrieving the pointer of the window.

    inside KTransferProgress Class there is a function called update which receives one value.
    It shall update the Progress Bar. But the emit updateEvent(number) does not do anything.

    I forgot to mention that the UDP Socket is running in another thread managed by boost::thread . I have chosen Boost::Thread because it supports termination of threads too. I know in normal use case you should not terminate the thread you should use the given way to abort a thread but for debug and some special cases termination can become handy.

    My Code
    KTransferProgress.hpp

    #pragma once
    
    #include <QWidget>
    #include<InternationalizationLib/Language.hpp>
    #include "ui_KTransferProgress.h"
    
    
    struct FileInformation {
    	QString from = "";
    	QString source = "";
    	QString target = "";
    	std::size_t size = 0;
    };
    Q_DECLARE_METATYPE(FileInformation)
    
    class KTransferProgress : public QWidget
    {
    	Q_OBJECT
    
    public:
    	KTransferProgress(const FileInformation& fi, const lang::Language& lang, QWidget *parent = Q_NULLPTR);
    	~KTransferProgress();
    
    	void update(uint64_t number);
    
    	Q_SIGNAL void updateEvent(uint64_t number);
    
    	void updateEventCallback(uint64_t number);
    
    protected:
    	void setupLanguage();
    	void setupCallbacks();
    
    private:
    	const lang::Language& lang;
    	Ui::KTransferProgress ui;
    };
    

    KTransferProgress.cpp

    #include "KTransferProgress.hpp"
    
    KTransferProgress::KTransferProgress(const FileInformation& fi, const lang::Language& lang, QWidget *parent) : lang(lang), QWidget(parent)
    {
    	ui.setupUi(this);
    	this->setupLanguage();
    	this->ui.txt_from->setText(fi.from);
    	this->ui.txt_source->setText(fi.source);
    	this->ui.txt_filesize->setText(QString::number(fi.size));
    	this->ui.txt_destination->setText(fi.target);
    	this->ui.pb_transfer->setMaximum(fi.size);
    	this->ui.pb_transfer->setValue(0);
    	
    }
    
    KTransferProgress::~KTransferProgress()
    {
    }
    
    void KTransferProgress::update(uint64_t number)
    {
    	emit this->updateEvent(number);
    }
    
    void KTransferProgress::updateEventCallback(uint64_t number)
    {
    	this->ui.pb_transfer->setValue(this->ui.pb_transfer->value() + number);
    }
    
    void KTransferProgress::setupLanguage() {
    	this->ui.lbl_from->setText(QString::fromStdU32String(this->lang["TransferProgress"]["label"]["lbl_from"]));
    	this->ui.lbl_source->setText(QString::fromStdU32String(this->lang["TransferProgress"]["label"]["lbl_source"]));
    	this->ui.lbl_filesize->setText(QString::fromStdU32String(this->lang["TransferProgress"]["label"]["lbl_filesize"]));
    	this->ui.lbl_target->setText(QString::fromStdU32String(this->lang["TransferProgress"]["label"]["lbl_target"]));
    }
    
    void KTransferProgress::setupCallbacks()
    {
    	connect(this, &KTransferProgress::updateEvent, this, &KTransferProgress::updateEventCallback);
    }
    

    The File-accepting Function

    void KSecureDesktopQT::acceptFileRequest(const QHostAddress& address, uint16_t port, std::string& source, std::string& receiver, const QString& target, const std::u16string& original, uint64_t filesize)
    {
        nlohmann::json response;
        response["action"] = static_cast<uint16_t>(ActionTypes::FileRequestAccept);
        response["source"] = source;
        response["receiver"] = receiver;
        response["path"] = original;
        FileInformation fi;
        fi.from = QString::fromStdString(source);
        fi.size = filesize;
        fi.source = QString::fromStdU16String(original);
        fi.target = target;
        std::promise<KTransferProgress*> prom;
        auto cont = prom.get_future();
        emit this->openTransferDialog(fi, prom);
        cont.wait();
        KTransferProgress* dlg_ptr = cont.get();
        auto str = response.dump();
        this->chatSocket.writeDatagram(str.c_str(), str.size(), address, port);
        if (!this->fileSocket.isListening())
            this->fileSocket.resumeAccepting();
        this->fileSocket.waitForNewConnection(60000);
        auto sock = this->fileSocket.nextPendingConnection();
        
        auto ip = sock->peerAddress();
        if (address != ip)
        {
            sock->close();
            delete sock;
            this->fileSocket.pauseAccepting();
            return;
        }
        //auto bytes = sock->readAll();
        QByteArray bytes;
        char* ch = new char[250];
        int len = 0;
        memset(ch, 0, 250);
        sock->waitForReadyRead();
        //auto bytes = sock->readAll();
        do {
            len = sock->read(ch, 250);
            bytes.append(ch, len);
            dlg_ptr->update(len);
        } while (len == 250);
        QSaveFile file(target);
        file.open(QIODevice::WriteOnly);
        file.write(bytes);
        if (file.commit()) {
            emit this->informationSignal(1, "Transfer Completed", "Transfer successfully completed");
            //QMessageBox::information(nullptr, "Transfer completed", "Transfer successfully completed");
            return;
        }
        emit this->informationSignal(2, "Transfer failed", "transfer failed");
        //QMessageBox::warning(nullptr, "Transfer incomplete", "Transfer failed");
    }
    

    OpenTransferDialog Event

    //SIGNAL in Header File is looking like this
    Q_SIGNAL void openTransferDialog(const FileInformation& fi, std::optional<std::reference_wrapper<std::promise<KTransferProgress*>>> dlg);
    //END
    
    void KSecureDesktopQT::openTransferEvent(const FileInformation& fi, std::optional<std::reference_wrapper<std::promise<KTransferProgress*>>> dlg)
    {
        auto prom = dlg.value();
        auto* ptr = new KTransferProgress(fi, this->language);
        ptr->show();
        prom.get().set_value(ptr);
    }
    

    Anyone knows why KTransferProgress::update does not do anything?



  • I found the missing part. I forgot the setupCallbacks in Constructor



  • I found the missing part. I forgot the setupCallbacks in Constructor


Log in to reply