raspberry pi1 중ltkmm의 2
7349 단어 gtkmmThreadRaspberryPi1
개요
raspberry pi1로 gtkmm 해봤어요.
한번 해 보았다.
사진.
샘플 코드 #include <gtkmm.h>
#include <gtkmm/application.h>
#include <sstream>
#include <chrono>
#include <iostream>
#include <thread>
#include <mutex>
class ExampleWindow;
class ExampleWorker
{
public:
ExampleWorker();
void do_work(ExampleWindow * caller);
void get_data(double * fraction_done, Glib::ustring * message) const;
void stop_work();
bool has_stopped() const;
private:
mutable std::mutex m_Mutex;
bool m_shall_stop;
bool m_has_stopped;
double m_fraction_done;
Glib::ustring m_message;
};
class ExampleWindow: public Gtk::Window
{
public:
ExampleWindow();
void notify();
private:
void on_start_button_clicked();
void on_stop_button_clicked();
void on_quit_button_clicked();
void update_start_stop_buttons();
void update_widgets();
void on_notification_from_worker_thread();
Gtk::Box m_VBox;
Gtk::ButtonBox m_ButtonBox;
Gtk::Button m_ButtonStart;
Gtk::Button m_ButtonStop;
Gtk::Button m_ButtonQuit;
Gtk::ProgressBar m_ProgressBar;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TextView m_TextView;
Glib::Dispatcher m_Dispatcher;
ExampleWorker m_Worker;
std::thread * m_WorkerThread;
};
ExampleWorker::ExampleWorker():
m_Mutex(),
m_shall_stop(false),
m_has_stopped(false),
m_fraction_done(0.0),
m_message()
{
}
void ExampleWorker::get_data(double * fraction_done, Glib::ustring * message) const
{
std::lock_guard<std::mutex> lock(m_Mutex);
if (fraction_done) * fraction_done = m_fraction_done;
if (message) * message = m_message;
}
void ExampleWorker::stop_work()
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = true;
}
bool ExampleWorker::has_stopped() const
{
std::lock_guard<std::mutex> lock(m_Mutex);
return m_has_stopped;
}
void ExampleWorker::do_work(ExampleWindow* caller)
{
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_has_stopped = false;
m_fraction_done = 0.0;
m_message = "";
}
for (int i = 0; ; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_fraction_done += 0.01;
if (i % 4 == 3)
{
std::ostringstream ostr;
ostr << (m_fraction_done * 100.0) << "% done\n";
m_message += ostr.str();
}
if (m_fraction_done >= 1.0)
{
m_message += "Finished";
break;
}
if (m_shall_stop)
{
m_message += "Stopped";
break;
}
}
caller->notify();
}
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = false;
m_has_stopped = true;
}
caller->notify();
}
ExampleWindow::ExampleWindow():
m_VBox(Gtk::ORIENTATION_VERTICAL, 5),
m_ButtonBox(Gtk::ORIENTATION_HORIZONTAL),
m_ButtonStart("Start work"),
m_ButtonStop("Stop work"),
m_ButtonQuit("_Quit", true),
m_ProgressBar(),
m_ScrolledWindow(),
m_TextView(),
m_Dispatcher(),
m_Worker(),
m_WorkerThread(nullptr)
{
set_title("Multi-threaded example");
set_border_width(5);
set_default_size(300, 300);
add(m_VBox);
m_VBox.pack_start(m_ProgressBar, Gtk::PACK_SHRINK);
m_ProgressBar.set_text("Fraction done");
m_ProgressBar.set_show_text();
m_ScrolledWindow.add(m_TextView);
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
m_TextView.set_editable(false);
m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStart, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStop, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonQuit, Gtk::PACK_SHRINK);
m_ButtonBox.set_border_width(5);
m_ButtonBox.set_spacing(5);
m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
m_ButtonStart.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_start_button_clicked));
m_ButtonStop.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_stop_button_clicked));
m_ButtonQuit.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_quit_button_clicked));
m_Dispatcher.connect(sigc::mem_fun(* this, &ExampleWindow::on_notification_from_worker_thread));
auto buffer = m_TextView.get_buffer();
buffer->create_mark("last_line", buffer->end(), true);
update_start_stop_buttons();
show_all_children();
}
void ExampleWindow::on_start_button_clicked()
{
if (m_WorkerThread)
{
std::cout << "Can't start a worker thread while another one is running." << std::endl;
}
else
{
m_WorkerThread = new std::thread([this] {
m_Worker.do_work(this);
});
}
update_start_stop_buttons();
}
void ExampleWindow::on_stop_button_clicked()
{
if (!m_WorkerThread)
{
std::cout << "Can't stop a worker thread. None is running." << std::endl;
}
else
{
m_Worker.stop_work();
m_ButtonStop.set_sensitive(false);
}
}
void ExampleWindow::update_start_stop_buttons()
{
const bool thread_is_running = m_WorkerThread != nullptr;
m_ButtonStart.set_sensitive(!thread_is_running);
m_ButtonStop.set_sensitive(thread_is_running);
}
void ExampleWindow::update_widgets()
{
double fraction_done;
Glib::ustring message_from_worker_thread;
m_Worker.get_data(&fraction_done, &message_from_worker_thread);
m_ProgressBar.set_fraction(fraction_done);
if (message_from_worker_thread != m_TextView.get_buffer()->get_text())
{
auto buffer = m_TextView.get_buffer();
buffer->set_text(message_from_worker_thread);
Gtk::TextIter iter = buffer->end();
iter.set_line_offset(0);
auto mark = buffer->get_mark("last_line");
buffer->move_mark(mark, iter);
m_TextView.scroll_to(mark);
}
}
void ExampleWindow::on_quit_button_clicked()
{
if (m_WorkerThread)
{
m_Worker.stop_work();
if (m_WorkerThread->joinable()) m_WorkerThread->join();
}
hide();
}
void ExampleWindow::notify()
{
m_Dispatcher.emit();
}
void ExampleWindow::on_notification_from_worker_thread()
{
if (m_WorkerThread && m_Worker.has_stopped())
{
if (m_WorkerThread->joinable()) m_WorkerThread->join();
delete m_WorkerThread;
m_WorkerThread = nullptr;
update_start_stop_buttons();
}
update_widgets();
}
int main(int argc, char * argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
ExampleWindow window;
return app->run(window);
}
이상.
Reference
이 문제에 관하여(raspberry pi1 중ltkmm의 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ohisama@github/items/907b47f4e1b0656ce8da
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
샘플 코드 #include <gtkmm.h>
#include <gtkmm/application.h>
#include <sstream>
#include <chrono>
#include <iostream>
#include <thread>
#include <mutex>
class ExampleWindow;
class ExampleWorker
{
public:
ExampleWorker();
void do_work(ExampleWindow * caller);
void get_data(double * fraction_done, Glib::ustring * message) const;
void stop_work();
bool has_stopped() const;
private:
mutable std::mutex m_Mutex;
bool m_shall_stop;
bool m_has_stopped;
double m_fraction_done;
Glib::ustring m_message;
};
class ExampleWindow: public Gtk::Window
{
public:
ExampleWindow();
void notify();
private:
void on_start_button_clicked();
void on_stop_button_clicked();
void on_quit_button_clicked();
void update_start_stop_buttons();
void update_widgets();
void on_notification_from_worker_thread();
Gtk::Box m_VBox;
Gtk::ButtonBox m_ButtonBox;
Gtk::Button m_ButtonStart;
Gtk::Button m_ButtonStop;
Gtk::Button m_ButtonQuit;
Gtk::ProgressBar m_ProgressBar;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TextView m_TextView;
Glib::Dispatcher m_Dispatcher;
ExampleWorker m_Worker;
std::thread * m_WorkerThread;
};
ExampleWorker::ExampleWorker():
m_Mutex(),
m_shall_stop(false),
m_has_stopped(false),
m_fraction_done(0.0),
m_message()
{
}
void ExampleWorker::get_data(double * fraction_done, Glib::ustring * message) const
{
std::lock_guard<std::mutex> lock(m_Mutex);
if (fraction_done) * fraction_done = m_fraction_done;
if (message) * message = m_message;
}
void ExampleWorker::stop_work()
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = true;
}
bool ExampleWorker::has_stopped() const
{
std::lock_guard<std::mutex> lock(m_Mutex);
return m_has_stopped;
}
void ExampleWorker::do_work(ExampleWindow* caller)
{
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_has_stopped = false;
m_fraction_done = 0.0;
m_message = "";
}
for (int i = 0; ; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_fraction_done += 0.01;
if (i % 4 == 3)
{
std::ostringstream ostr;
ostr << (m_fraction_done * 100.0) << "% done\n";
m_message += ostr.str();
}
if (m_fraction_done >= 1.0)
{
m_message += "Finished";
break;
}
if (m_shall_stop)
{
m_message += "Stopped";
break;
}
}
caller->notify();
}
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = false;
m_has_stopped = true;
}
caller->notify();
}
ExampleWindow::ExampleWindow():
m_VBox(Gtk::ORIENTATION_VERTICAL, 5),
m_ButtonBox(Gtk::ORIENTATION_HORIZONTAL),
m_ButtonStart("Start work"),
m_ButtonStop("Stop work"),
m_ButtonQuit("_Quit", true),
m_ProgressBar(),
m_ScrolledWindow(),
m_TextView(),
m_Dispatcher(),
m_Worker(),
m_WorkerThread(nullptr)
{
set_title("Multi-threaded example");
set_border_width(5);
set_default_size(300, 300);
add(m_VBox);
m_VBox.pack_start(m_ProgressBar, Gtk::PACK_SHRINK);
m_ProgressBar.set_text("Fraction done");
m_ProgressBar.set_show_text();
m_ScrolledWindow.add(m_TextView);
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
m_TextView.set_editable(false);
m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStart, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStop, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonQuit, Gtk::PACK_SHRINK);
m_ButtonBox.set_border_width(5);
m_ButtonBox.set_spacing(5);
m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
m_ButtonStart.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_start_button_clicked));
m_ButtonStop.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_stop_button_clicked));
m_ButtonQuit.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_quit_button_clicked));
m_Dispatcher.connect(sigc::mem_fun(* this, &ExampleWindow::on_notification_from_worker_thread));
auto buffer = m_TextView.get_buffer();
buffer->create_mark("last_line", buffer->end(), true);
update_start_stop_buttons();
show_all_children();
}
void ExampleWindow::on_start_button_clicked()
{
if (m_WorkerThread)
{
std::cout << "Can't start a worker thread while another one is running." << std::endl;
}
else
{
m_WorkerThread = new std::thread([this] {
m_Worker.do_work(this);
});
}
update_start_stop_buttons();
}
void ExampleWindow::on_stop_button_clicked()
{
if (!m_WorkerThread)
{
std::cout << "Can't stop a worker thread. None is running." << std::endl;
}
else
{
m_Worker.stop_work();
m_ButtonStop.set_sensitive(false);
}
}
void ExampleWindow::update_start_stop_buttons()
{
const bool thread_is_running = m_WorkerThread != nullptr;
m_ButtonStart.set_sensitive(!thread_is_running);
m_ButtonStop.set_sensitive(thread_is_running);
}
void ExampleWindow::update_widgets()
{
double fraction_done;
Glib::ustring message_from_worker_thread;
m_Worker.get_data(&fraction_done, &message_from_worker_thread);
m_ProgressBar.set_fraction(fraction_done);
if (message_from_worker_thread != m_TextView.get_buffer()->get_text())
{
auto buffer = m_TextView.get_buffer();
buffer->set_text(message_from_worker_thread);
Gtk::TextIter iter = buffer->end();
iter.set_line_offset(0);
auto mark = buffer->get_mark("last_line");
buffer->move_mark(mark, iter);
m_TextView.scroll_to(mark);
}
}
void ExampleWindow::on_quit_button_clicked()
{
if (m_WorkerThread)
{
m_Worker.stop_work();
if (m_WorkerThread->joinable()) m_WorkerThread->join();
}
hide();
}
void ExampleWindow::notify()
{
m_Dispatcher.emit();
}
void ExampleWindow::on_notification_from_worker_thread()
{
if (m_WorkerThread && m_Worker.has_stopped())
{
if (m_WorkerThread->joinable()) m_WorkerThread->join();
delete m_WorkerThread;
m_WorkerThread = nullptr;
update_start_stop_buttons();
}
update_widgets();
}
int main(int argc, char * argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
ExampleWindow window;
return app->run(window);
}
이상.
Reference
이 문제에 관하여(raspberry pi1 중ltkmm의 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ohisama@github/items/907b47f4e1b0656ce8da
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
#include <gtkmm.h>
#include <gtkmm/application.h>
#include <sstream>
#include <chrono>
#include <iostream>
#include <thread>
#include <mutex>
class ExampleWindow;
class ExampleWorker
{
public:
ExampleWorker();
void do_work(ExampleWindow * caller);
void get_data(double * fraction_done, Glib::ustring * message) const;
void stop_work();
bool has_stopped() const;
private:
mutable std::mutex m_Mutex;
bool m_shall_stop;
bool m_has_stopped;
double m_fraction_done;
Glib::ustring m_message;
};
class ExampleWindow: public Gtk::Window
{
public:
ExampleWindow();
void notify();
private:
void on_start_button_clicked();
void on_stop_button_clicked();
void on_quit_button_clicked();
void update_start_stop_buttons();
void update_widgets();
void on_notification_from_worker_thread();
Gtk::Box m_VBox;
Gtk::ButtonBox m_ButtonBox;
Gtk::Button m_ButtonStart;
Gtk::Button m_ButtonStop;
Gtk::Button m_ButtonQuit;
Gtk::ProgressBar m_ProgressBar;
Gtk::ScrolledWindow m_ScrolledWindow;
Gtk::TextView m_TextView;
Glib::Dispatcher m_Dispatcher;
ExampleWorker m_Worker;
std::thread * m_WorkerThread;
};
ExampleWorker::ExampleWorker():
m_Mutex(),
m_shall_stop(false),
m_has_stopped(false),
m_fraction_done(0.0),
m_message()
{
}
void ExampleWorker::get_data(double * fraction_done, Glib::ustring * message) const
{
std::lock_guard<std::mutex> lock(m_Mutex);
if (fraction_done) * fraction_done = m_fraction_done;
if (message) * message = m_message;
}
void ExampleWorker::stop_work()
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = true;
}
bool ExampleWorker::has_stopped() const
{
std::lock_guard<std::mutex> lock(m_Mutex);
return m_has_stopped;
}
void ExampleWorker::do_work(ExampleWindow* caller)
{
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_has_stopped = false;
m_fraction_done = 0.0;
m_message = "";
}
for (int i = 0; ; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(250));
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_fraction_done += 0.01;
if (i % 4 == 3)
{
std::ostringstream ostr;
ostr << (m_fraction_done * 100.0) << "% done\n";
m_message += ostr.str();
}
if (m_fraction_done >= 1.0)
{
m_message += "Finished";
break;
}
if (m_shall_stop)
{
m_message += "Stopped";
break;
}
}
caller->notify();
}
{
std::lock_guard<std::mutex> lock(m_Mutex);
m_shall_stop = false;
m_has_stopped = true;
}
caller->notify();
}
ExampleWindow::ExampleWindow():
m_VBox(Gtk::ORIENTATION_VERTICAL, 5),
m_ButtonBox(Gtk::ORIENTATION_HORIZONTAL),
m_ButtonStart("Start work"),
m_ButtonStop("Stop work"),
m_ButtonQuit("_Quit", true),
m_ProgressBar(),
m_ScrolledWindow(),
m_TextView(),
m_Dispatcher(),
m_Worker(),
m_WorkerThread(nullptr)
{
set_title("Multi-threaded example");
set_border_width(5);
set_default_size(300, 300);
add(m_VBox);
m_VBox.pack_start(m_ProgressBar, Gtk::PACK_SHRINK);
m_ProgressBar.set_text("Fraction done");
m_ProgressBar.set_show_text();
m_ScrolledWindow.add(m_TextView);
m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
m_VBox.pack_start(m_ScrolledWindow);
m_TextView.set_editable(false);
m_VBox.pack_start(m_ButtonBox, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStart, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonStop, Gtk::PACK_SHRINK);
m_ButtonBox.pack_start(m_ButtonQuit, Gtk::PACK_SHRINK);
m_ButtonBox.set_border_width(5);
m_ButtonBox.set_spacing(5);
m_ButtonBox.set_layout(Gtk::BUTTONBOX_END);
m_ButtonStart.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_start_button_clicked));
m_ButtonStop.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_stop_button_clicked));
m_ButtonQuit.signal_clicked().connect(sigc::mem_fun(* this, &ExampleWindow::on_quit_button_clicked));
m_Dispatcher.connect(sigc::mem_fun(* this, &ExampleWindow::on_notification_from_worker_thread));
auto buffer = m_TextView.get_buffer();
buffer->create_mark("last_line", buffer->end(), true);
update_start_stop_buttons();
show_all_children();
}
void ExampleWindow::on_start_button_clicked()
{
if (m_WorkerThread)
{
std::cout << "Can't start a worker thread while another one is running." << std::endl;
}
else
{
m_WorkerThread = new std::thread([this] {
m_Worker.do_work(this);
});
}
update_start_stop_buttons();
}
void ExampleWindow::on_stop_button_clicked()
{
if (!m_WorkerThread)
{
std::cout << "Can't stop a worker thread. None is running." << std::endl;
}
else
{
m_Worker.stop_work();
m_ButtonStop.set_sensitive(false);
}
}
void ExampleWindow::update_start_stop_buttons()
{
const bool thread_is_running = m_WorkerThread != nullptr;
m_ButtonStart.set_sensitive(!thread_is_running);
m_ButtonStop.set_sensitive(thread_is_running);
}
void ExampleWindow::update_widgets()
{
double fraction_done;
Glib::ustring message_from_worker_thread;
m_Worker.get_data(&fraction_done, &message_from_worker_thread);
m_ProgressBar.set_fraction(fraction_done);
if (message_from_worker_thread != m_TextView.get_buffer()->get_text())
{
auto buffer = m_TextView.get_buffer();
buffer->set_text(message_from_worker_thread);
Gtk::TextIter iter = buffer->end();
iter.set_line_offset(0);
auto mark = buffer->get_mark("last_line");
buffer->move_mark(mark, iter);
m_TextView.scroll_to(mark);
}
}
void ExampleWindow::on_quit_button_clicked()
{
if (m_WorkerThread)
{
m_Worker.stop_work();
if (m_WorkerThread->joinable()) m_WorkerThread->join();
}
hide();
}
void ExampleWindow::notify()
{
m_Dispatcher.emit();
}
void ExampleWindow::on_notification_from_worker_thread()
{
if (m_WorkerThread && m_Worker.has_stopped())
{
if (m_WorkerThread->joinable()) m_WorkerThread->join();
delete m_WorkerThread;
m_WorkerThread = nullptr;
update_start_stop_buttons();
}
update_widgets();
}
int main(int argc, char * argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
ExampleWindow window;
return app->run(window);
}
Reference
이 문제에 관하여(raspberry pi1 중ltkmm의 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ohisama@github/items/907b47f4e1b0656ce8da텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)