Zeichnen mit Gtk+

Der Wolf

Erfahrenes Mitglied
Hallo,

ich versuche gerade mit Gtk+ ein paar Pfeile/Linien zu zeichnen. Die paar GUI Elemente zeigt mir mein Programm bisher auch richtig an, aber sobald ich ein weisses Rechteck oder ähnliches malen will, frisst das Programm plötzlich 100% meiner CPU und wird extrem langsam. Und ich habe immernoch keine Ahnung woran das liegen könnte. Für ein paar Tipps/Hilfen wäre ich also sehr dankbar. Ich programmiere das ganze mit Gtk unter Ubuntu 8.10.

Die relevanten Programmteile sehen bisher so aus ...
Code:
	while (mainLoopRunning) {

		// Get start time.
		gettimeofday(&time, NULL);
		start = (((uint64_t) time.tv_sec)*1000) + (((uint64_t) time.tv_usec)/1000);

		usleep(100);

		// Draw all found objects.
		drawObjects(NULL);
/**		int nrLocs = amReader->getNrLocations();
		if (nrLocs) {

			for (int i = 0; i < nrLocs; i++) { 
			
				drawObjects(amReader->getLocation(i));			
	
			}
		}
*/

		// Wait until GTK is ready.
		while (g_main_iteration(FALSE));

		// estimating calculating time
		gettimeofday(&time, NULL);	

		// Slowing down.
		stop = (((uint64_t) time.tv_sec)*1000) + (((uint64_t) time.tv_usec)/1000);
	
		// slowing down frequency of main loop -> AM performance!
		uint64_t diff = stop - start;
		if (100 > (1000 * diff)) {
	
			usleep(100 - (1000 * diff));

		}  

		// Show information output every 3 seconds.gettimeofday(&time, NULL);
		long timeSec = time.tv_sec;
		long timeUSec = time.tv_usec;
		uint64_t currentTime	= (uint64_t)timeSec*1000  + (uint64_t)timeUSec/1000;
		diff									= currentTime - lastShown;		
	
		if (diff > 3000) {

			std::cout << "There are at least " << amReader->getNrLocations() << " in the scene." << std::endl;

			lastShown = currentTime;

		}		

	}

Code:
int
main(int argc, char* argv[]) {

	// Parse command line parameters
	clo::parser parser;
	try {
		parser.parse(argc, argv);
	} catch (clo::autoexcept &e) {
		switch (e.get_autothrow_id()) {
			case clo::autothrow_help:
			std::cout << "Usage: " << argv[0] << " [options]\n";
			std::cout << e.what();
			exit(1);
		}
	}

	const clo::options &options = parser.get_options();	

	memoryName	= options.activeMemory;
	xPath				= options.xPath;	

	// Initialise gtk mode.
	gtk_init(&argc, &argv);

	initMainWindow();
	initDrawingComponents();

	gtk_init_add(startMainLoop, NULL);
	gtk_main();

}

Code:
#include "MemVis.h"

// Global used gtk stuff.
GtkWidget	*canvas;

GdkGC			*normal;
GdkGC			*pixmap;

GdkPixmap	*visual;

GdkColor	*white;
GdkColor	*black;

void
drawObjects(xmltio::Location *loc) {	

	// Clear drawing area.
	int width = 0, height = 0;
	gdk_window_get_size(canvas->window, &width, &height);
	gdk_draw_rectangle(visual, pixmap, TRUE, 0, 0, width, height);

	// Show all ...
	gdk_draw_pixmap(canvas->window, normal, visual, 0, 0, 0, 0, width, height);


}

void
drawArrow(float angle, float length) {

	gdk_gc_set_line_attributes(normal, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_MITER);

	int width = 0, height = 0;
	gdk_window_get_size(canvas->window, &width, &height);

	int xPos1  = (int) ceil((float) width / 2);
	int yPos1  = (int) ceil(0.0);
	int faktor = (int) ceil((float) width / 2) - 10;

	int xPos2  = (int) ceil( ((float) width / 2) - (cos(angle+(3.1415 / 2)) * (float)faktor * (float)length / (float) 2000) );
	int yPos2  = (int) ceil( (sin(angle + (3.1415/2) ) * (float) faktor * (float) length / (float) 2000));

	gdk_draw_line( visual, normal, xPos1, yPos1, xPos2, yPos2);

}

void
initDrawingComponents() {

	visual   = gdk_pixmap_new(canvas->window, gdk_screen_width(), gdk_screen_height(), -1);

	black	= (GdkColor*) malloc(sizeof(GdkColor));
	black->red		= 0;
	black->green	= 0;
	black->blue		= 0;
	black->pixel	= (gulong)(0);
	gdk_color_alloc(gtk_widget_get_colormap(canvas), black);

	white = (GdkColor*) malloc(sizeof(GdkColor));
  white->red		= 65535;
  white->green	= 65535;
  white->blue		= 65535;
  white->pixel	= (gulong)(255+65536+255*65536);
  gdk_color_alloc(gtk_widget_get_colormap(canvas), white);

	normal = gdk_gc_new(canvas->window);
	gdk_gc_set_foreground(normal, black);
	gdk_gc_set_background(normal, white);

	pixmap = gdk_gc_new(canvas->window);
	gdk_gc_set_foreground(pixmap, white);
	gdk_gc_set_background(pixmap, white);

}

void
initMainWindow() {

	gdk_rgb_init();
  gtk_widget_set_default_colormap (gdk_rgb_get_cmap());
  gtk_widget_set_default_visual (gdk_rgb_get_visual());

  // Initialise main window.
	GtkWidget *mainWindow	= gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size(GTK_WINDOW(mainWindow) , 800, 600);
	gtk_window_set_title(GTK_WINDOW(mainWindow) , "Visualize objects.");
	gtk_signal_connect(GTK_OBJECT(mainWindow), "destroy", GTK_SIGNAL_FUNC(quitMainLoop), NULL);

	// Initialise canvas.
	GtkWidget *visualFrame = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME (visualFrame), GTK_SHADOW_IN);
	gtk_container_add(GTK_CONTAINER (mainWindow), visualFrame);
	gtk_widget_show(visualFrame);

	gtk_widget_set_usize (visualFrame, 800 - 140 , 600 - 200);
	
	canvas = gtk_drawing_area_new();	
	gtk_container_add(GTK_CONTAINER(visualFrame), canvas);
	gtk_widget_show(canvas);

	// Show main window.
	gtk_widget_show(mainWindow);	

}

Gruß
Der Wolf
 
Zuletzt bearbeitet:
Zurück