ProgressBar->setValue() crash



  • hi,

    does somebody know why this crash after the Signal emitted?

    Pseudo Code:

    @class FormMain : public QMainWindow
    {
    Q_OBJECT:

    public:
    FormMain(void)
    {
    connect(pointerToClassA, SIGNAL(&A::SignalUpdateProgressBar(int)), this, SLOT(EventUpdateProgressBar(int)));
    }

    public slots:
    EventUpdateProgressBar(int)
    {
    UI->progressbar->setValue(int);
    }
    }

    class A : public QObject
    {
    Q_OBJECT:

    public:
    A()
    {
    // other thread (non QT) calls SignalUpdateProgressBar
    OtherClass->setEvent(GET_VALUE, std::bind(&A::SignalUpdateProgressBar, this, std::placeholder_1));
    }
    public signals:
    SignalUpdateProgressBar(int)
    {
    emit PointerToFormMain->EventUpdateProgressBar(int);
    }
    }@


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Your code looks wrong in several places:

    • signals don't have implementation, you just emit them at the right place.
    • You don't initialize UI so progressbar doesn't exist either.
    • PointerToFromMain should not exist at all, an instance of A is connected in FormMain and should know nothing about it.

    You should have a look at the examples of Qt for proper use of signals and slots, as well as designer based UI.



  • Hi, thank you.

    bq. signals don’t have implementation, you just emit them at the right place.

    I'am connecting SignalUpdateProgressBar(int) which is implemented in Class A as public Signal.
    That Signal is called later by an Event from another non qt thread, the function throw the emit and the Slot being called? All works fine, but after updating the progressbar the application Crash.

    bq. You don’t initialize UI so progressbar doesn’t exist either.

    Yes, because this above is more or less pseudo code.

    bq. PointerToFromMain should not exist at all, an instance of A is connected in FormMain and should know nothing about it.

    A PointerToFromMain doesn't exist to all, the pointer is passed by constructor of Class A, but i wrote some ugly and absurd pseudo code for demonstrating, sorry.

    Here is an good example:

    @class FormMain : public QMainWindow
    {
    Q_OBJECT
    public:
    FormMain(QWidget *parent = 0)
    : QMainWindow(parent)
    {
    // setting up
    _ui.setupUi(this);
    _core = std::unique_ptrNT::NCore(new NT::NCore);

    // connecting signals & slots
    connect(this, SIGNAL(SignalCharacterHealth(int)), this, SLOT(EventCharacterHealth(int)), Qt::QueuedConnection);

    // i'am hooking an game function, after the movement function getting called, the game thread calls SignalCharacterMovement
    _core->Player->OnReceiveHealth(std::bind(&FormMain::SignalCharacterHealth, this, std::placeholders::_1));
    }

    ~FormMain(void);

    private:
    Ui::MainWindow _ui;
    std::unique_ptrNT::NCore _core;

    void SignalCharacterHealth(int percent);
    {
    emit EventCharacterHealth(percent);
    }

    private slots:
    void EventCharacterHealth(int percent)
    {
    // crash
    _ui->progressBar->setValue(percent);
    }
    };@



  • Pff, sorry to say, but did you ever hear of coding standards? For C++ a nice rule is to minimize the function definitions in the class declaration! Place the definitions in the source file, not in the header file!
    This class declaration/description is almost unreadable.
    For your problem, use the debugger and test if _ui is actually set when progressBar is being set.



  • That was for demonstration!
    And yes, the _ui was set before progressBar is being set.



  • bq. Pff, sorry to say, but did you ever hear of coding standards? For C++ a nice rule is to minimize the function definitions in the class declaration!

    imho that it's not really true: you're allowed by the C++ standard to do so, taking the advantage that those member functions will be inline by default: i.e. this is suitable in general for functions which are not changed frequently like getters and setters are



  • @ void SignalCharacterHealth(int percent);
    {
    emit EventCharacterHealth(percent);
    }@

    I think:
    EventCharacterHealth is a slot in your code and by the line above you directly call a function trying to update from other thread the progressbar living in app's main thread which is forbidden



  • Hi, thank you.
    Yes that is it, i checked the thread id's and they are different.
    So EventCharacterHealth is called by other thread and the progressbar is updating by other thread to, which is forbidden how you said.

    I think i misunderstand something, how i should raise up the Signal correctly?
    Thought after emit EventCharacterHealth() is reached, the app's main thread calls EventCharacterHealth() wich is connected.



  • Got it, thanks for the answers guys, just misunderstood the Signal/Slot mechanism!!
    Implementation was missing and emit not needed, cause the Event handler call the Signal.
    Now it works fine.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.