Trådsäkerhet åter igen

Att skapa fönster med; Qt, Gtk, Gnome m.m.
Post Reply
Pacman
Posts: 496
Joined: 13 October 2002, 13:21
Contact:

Trådsäkerhet åter igen

Post by Pacman » 18 July 2004, 21:13

Ok, nu är jag här med mina trådar igen. Men denna gången kommer jag lägga med lite exempel kod för att kunna reda ut precis vad det är jag vill.

Code: Select all

#include <gtkmm.h>
#include <sigc++/class_slot.h>
#include <sstream>

/*
 *	Test Window
 *
 */

class TestWindow : public Gtk::Window
{
public:
	TestWindow();
	
	// Skapar en ny tråd med run()-funktionen
	void launch();

private:
	Gtk::VBox boxMain;

	class TreeColumns : public Gtk::TreeModel::ColumnRecord
	{
	public:
		TreeColumns()
		{
			add( colText );
		}
		
		Gtk::TreeModelColumn<Glib::ustring> colText;
	};

	// Lista som visar lite textmeddelanden
	Gtk::TreeView treeView;
	Gtk::ScrolledWindow scrolledWindow;
	Glib::RefPtr<Gtk::ListStore> treeModel;
	TreeColumns treeColumns;

	// Lägg till meddelande i listan
	void addMessage( Glib::ustring text );

	// Funktionen som trådas ut och lägger till meddelanden i listan
	void run();
	
};

TestWindow::TestWindow()
{
	// Ändra några attribut
	set_title( "Test window" );
	set_border_width( 5 );
	set_default_size( 300, 300 );
	
	// Sätt ihop en lista och lägg i huvudboxen
	treeModel = Gtk::ListStore::create( treeColumns );
	treeView.set_model( treeModel );
	treeView.append_column( "Message", treeColumns.colText );
	scrolledWindow.add( treeView );
	scrolledWindow.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
	boxMain.pack_start( scrolledWindow, Gtk::PACK_EXPAND_WIDGET );

	// Lägg huvudboxen i fönstret och visa alla objekt
	add( boxMain );
	show_all_children();
}

void TestWindow::launch()
{
	// Tråda ut run()-funktionen
	Glib::Thread::create( SigC::slot_class( *this, &TestWindow::run ), false );
}

void TestWindow::addMessage( Glib::ustring text )
{
	// Skapa en ny rad i listan och ändra texten i den
	Gtk::TreeModel::Row row = *( treeModel->append() );
	row[ treeColumns.colText ] = text;
}

void TestWindow::run()
{
	unsigned int i;
	std::stringstream sstream;

	/*
	 *	Detta måste fixas. Denna funktionen ska kunna ändra ALLA objekt
	 *	i GUI:et helt trådsäkert på något sätt.
	 *
	 */
	for( i = 0; i < 1000; i++ )
	{
		sstream.str( "" );
		sstream << i;

		// Lägg till ett meddelande
		addMessage( "Test " + sstream.str() );
	}
}

/*
 *	Main window
 *
 */

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

private:
	// Visa ett test fönstret
	void showTestWindow();

	Gtk::VBox boxMain;

};

MainWindow::MainWindow()
{
	set_title( "Main window" );
	set_border_width( 5 );
	set_default_size( 300, 300 );
	
	Gtk::Button *button = new Gtk::Button( "Show window" );
	boxMain.pack_start( *manage( button ), Gtk::PACK_SHRINK );
	button->signal_clicked().connect(
		sigc::mem_fun( *this, &MainWindow::showTestWindow ) );
	
	button = new Gtk::Button( "Exit" );
	boxMain.pack_start( *manage( button ), Gtk::PACK_SHRINK );
	button->signal_clicked().connect(
		sigc::mem_fun( *this, &MainWindow::hide ) );

	add( boxMain );
	show_all_children();
}

void MainWindow::showTestWindow()
{
	TestWindow *window = new TestWindow();
	window->set_modal( true );
	window->set_transient_for( *this );

	// Skapa en ny tråd när fönstret idl:ar
	Glib::signal_idle().connect( sigc::bind_return(
		sigc::mem_fun( window, &TestWindow::launch ), false ) );
		
	window->show();
}

/*
 *	Main
 *
 */

int main( int argc, char *argv[] )
{
	Glib::thread_init();
	Gtk::Main kit( argc, argv );

	MainWindow main;
	Gtk::Main::run( main );

	return 0;
}
Det jag vill åstakomma är att run()-funktionen i TestWindow-klassen ska vara HELT trådsäker. Jag ska alltså kunna ändra, lägga till, ta bort grafiska komponenter och objekt från den. Varför? Jo, därför att jag ska senare göra en dialog till ett program som läser in massa data successivt och mellan varje grej som görs så ska text läggas till i listan samt lite andra objekt ska ändras från den här funktionen. Därför måste jag ha ett smidigt sätt att göra detta, vilket jag inte hittar nånstans. Ge mig gärna lite tips och länkar, för jag är verkligen helt lost på den här delen. Lite exempel kod som passar in till ovanstående kod vore hur bra som helst, dock så vill jag inte låsa in mig till just den här koden, eftersom den jag använder egentligen är mer komplex.
"Make 'emerge -u world', not 'rm -rf /'"

Guest

Post by Guest » 27 July 2004, 10:03

Du kanske hittar nåt på http://www.gtkmm.org och om du inte gillar dom inbyggda trådningsbiblioteken kan du ju testa dom i SDL som är mycket lättanvända, skapar ju en till dependencie i ditt program iofs.

Pacman
Posts: 496
Joined: 13 October 2002, 13:21
Contact:

Post by Pacman » 27 July 2004, 16:18

Bjqrn wrote:Du kanske hittar nåt på http://www.gtkmm.org och om du inte gillar dom inbyggda trådningsbiblioteken kan du ju testa dom i SDL som är mycket lättanvända, skapar ju en till dependencie i ditt program iofs.
gtkmm.org är min huvudkälla tillsammans med google, och det finns ingen vettig information kring detta. Och SDL vill jag inte dra in i mitt projekt, för det ska gå att lösa utan. Men det får ligga på is tills vidare, orkar inte med projektet just nu.
"Make 'emerge -u world', not 'rm -rf /'"

Guest

Post by Guest » 27 July 2004, 16:55

OK

User avatar
panzar
Posts: 100
Joined: 23 April 2003, 22:07

Post by panzar » 27 July 2004, 18:51

Pacman wrote:Men det får ligga på is tills vidare, orkar inte med projektet just nu.
Lägger du hela projektet med SE Manager på is? Eller bara denna delen?

Pacman
Posts: 496
Joined: 13 October 2002, 13:21
Contact:

Post by Pacman » 27 July 2004, 19:13

panzar wrote:
Pacman wrote:Men det får ligga på is tills vidare, orkar inte med projektet just nu.
Lägger du hela projektet med SE Manager på is? Eller bara denna delen?
Jag lägger hels SE Manager på is tills vidare. Har en hel del annat att göra just nu, som jag prioriterar.
"Make 'emerge -u world', not 'rm -rf /'"

Post Reply