I'm learning gtk, I wanted to write a program in which the UI works in one thread and the entire program logic is in the other. Based on the data from the logic thread, the UI thread should flash a red light. Unfortunately, it only works for a while and then stops. Moving/clicking the mouse fixes the problem for a while, and an error from the topic appears in the console

main.cpp:

#include "myarea.h"
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <iostream>
#include <thread> 

class ExampleWindow : public Gtk::Window
{
public:
    ExampleWindow();

    void ping();

    void threadFunction();

protected:
    MyArea m_area;
};

ExampleWindow::ExampleWindow()
{
    set_title("DrawingArea");
    set_child(m_area);

    std::thread(&ExampleWindow::threadFunction, this).detach();
}

void ExampleWindow::ping()
{
    // Tu można umieścić kod, który będzie wykonywany w głównym wątku

    if (m_area.isColorful == false)
    {
        m_area.isColorful = true;
        std::cout << m_area.isColorful << " true" << std::endl;
    }
    else
    {
        m_area.isColorful = false;
        std::cout << m_area.isColorful << " false" << std::endl;
    }

    m_area.queue_draw();
}

void ExampleWindow::threadFunction()
{
    m_area.isColorful = false;

    while (true)
    {
        ping();

        std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    }
}

int main(int argc, char** argv)
{
    auto app = Gtk::Application::create("org.gtkmm.example");

    return app->make_window_and_run<ExampleWindow>(argc, argv);
}

myarea.cpp:

#define _USE_MATH_DEFINES

#include "myarea.h"
#include <cairomm/context.h>
#include <math.h>

MyArea::MyArea()
{
    set_draw_func(sigc::mem_fun(*this, &MyArea::on_draw));
}

MyArea::~MyArea()
{
}

void MyArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height)
{
    const int lesser = std::min(width, height);

    // coordinates for the center of the window
    const int xc = width / 2;
    const int yc = height / 2;

    cr->set_line_width(lesser * 0.02);  // outline thickness changes
    // with window size

    cr->save();
    cr->arc(xc, yc, lesser / 4.0, 0.0, 2.0 * M_PI); // full circle

    if (isColorful) {
        cr->set_source_rgba(0.8, 0.0, 0.0, 1); // Red, partially translucent
    }
    else {
        cr->set_source_rgba(0.5, 0.5, 0.5, 1); // Gray, partially translucent
    }

    cr->fill_preserve();

    if (isColorful) {
        cr->set_source_rgba(0.6, 0.0, 0.0, 1); // Red, partially translucent
    }
    else {
        cr->set_source_rgba(0.4, 0.4, 0.4, 1); // Gray, partially translucent
    }
    cr->stroke();

    cr->restore();  // back to opaque black
}

myarea.h:

#pragma once

#include <gtkmm/drawingarea.h>

class MyArea : public Gtk::DrawingArea
{
public:
    MyArea();
    virtual ~MyArea();

    bool isColorful;

protected:
    void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);
};

are you able to help me? or find a starting point?

I need to be able to update ui based on results from elsewhere in the program.

0

There are 0 best solutions below