صفيف من نوع تعويم يعمل كمدخل. يقوم البرنامج بتنظيم العرض ، التمدد ، التمرير في الرسم البياني.نمط الكتابة هو C مع الفئات (بدون gtkmm). تبين أنها ليست مثالية ، مع تجريد التدفق. على وجه الخصوص ، تؤدي وظائف رد الاتصال إلى تدهور التغليف ، ويجب نقل جزء كبير من المتغيرات إلى القسم العام.بشكل أساسي ، يمكن وضع وظائف رد الاتصال في ملف جنبًا إلى جنب مع بقية وظائف الفئة ، والتي دعوتها إلى المعلمات الرسومية. في GTK ، كل نوع من عناصر واجهة المستخدم له إشاراته الخاصة ، وبعضها موروث. على سبيل المثال ، يحتوي GtkEventBox على إشارة "button-press-event" ، ولكن ليس لديه "الحدث-التكوين" المطلوب للرد على تغيير حجم الأداة ، لأن GtkEventBox يأخذ دائمًا حجم المحتوى. ويتم تعيين حجم المحتوى باليد. يمكنك استخدام حاوية GtkFrame.cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cr = cairo_create(surface);
في cairo_t ، يتم إنشاء الخطوط والعلامات التي يتم عرضها بواسطة دالة cairo_stroke. عند التنميط ، اتضح أن cairo_stroke يستغرق الكثير من وقت المعالج ، لذلك يجب استخدامه بأقل قدر ممكن ، ووقت التنفيذ لوظائف
مثل cairo_move_to ، cairo_line_to صغير جدًا. بعد cairo_stroke ، يتم مسح محتويات cairo_t ولن يؤدي استدعاء cairo_stroke (cr) مرة أخرى إلى إخراج أي شيء. يمكنك استخدام
cairo_stroke_preserve لحفظ المحتوى و cairo_save / cairo_restore ، لكنني لم أستخدمها.
إذا تم تغيير الأبعاد (عن طريق التمدد بالماوس ، إشارة config_event_cb) ، فمن الضروري لكل رسم رسم وإعادة إنشاء cairo_surface_t و cairo_t. إذا قمت بإرجاع الجدول الزمني ، فلا داعي لإعادة إنشائه
cairo_set_source_rgb(cr,0.8,0.8,0.8);
cairo_paint(cr);
بعد ذلك ، يتم ترجمة cairo_surface_t إلى صورةvoid gtk_image_set_from_surface (GtkImage *image, cairo_surface_t *surface);
ثم يتم إدراج هذه الصورة على النحو التاليeventbox=gtk_event_box_new();
g_signal_connect(eventbox,"button-press-event", G_CALLBACK(eventbox_press_cb), this);
GtkAdjustment *adj_h=gtk_adjustment_new(0,0,100,1,5,10);
GtkAdjustment *adj_v=gtk_adjustment_new(0,0,100,1,5,10);
GtkWidget *viewport=gtk_viewport_new(adj_h, adj_v);
scrolledwindow=gtk_scrolled_window_new(adj_h, adj_v);
g_object_set(scrolledwindow, "hscrollbar-policy", GTK_POLICY_EXTERNAL, "vscrollbar-policy", GTK_POLICY_EXTERNAL, NULL);
gtk_container_add(GTK_CONTAINER(viewport), scrolledwindow);
gtk_widget_set_events(scrolledwindow, GDK_SCROLL_MASK);
g_signal_connect(scrolledwindow,"scroll-event",G_CALLBACK(eventbox_scroll_cb), this);
GtkWidget *box=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
adj=gtk_adjustment_new(0,0,110,1,5,10);
g_signal_connect(adj,"value-changed", G_CALLBACK(adj_changed_cb), this);
scrollbar=gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL,adj);
gtk_box_pack_end(GTK_BOX(box),scrollbar, FALSE,FALSE,0);
image_from_surface=gtk_image_new_from_surface(surface);
gtk_container_add(GTK_CONTAINER(scrolledwindow),image_from_surface);
gtk_box_pack_start(GTK_BOX(box),viewport, TRUE,TRUE,0);
gtk_container_add(GTK_CONTAINER(eventbox),box);
لقد قمت بإزالة البادئات ، على سبيل المثال ، النوافذ المتحركة التي تم تمريرها من النوع GtkScrolledWindow.ترتيب المرفقات لفترة وجيزة صورة>> نافذة عرضية -> إطار عرض -> مربع -> صندوق الأحداث -> (إطار)إذا قمت بإزالة نافذة عرض قابلة للتمرير-> حاويات إطار العرض ، فسيزداد الرسم البياني فقط ، ولكنه لن ينخفض. يضيف مربع التمرير. قد تلاحظ أن هناك 3 ، ولكن لم يتم استخدام 2 منها وهي مطلوبة فقط لتهيئة الحاويات اللازمة. يتم استخدام وظيفة gtk_container_add في عناصر واجهة استخدام الحاوية حيث تناسب عنصر واجهة طفل واحد. يعين g_object_set خصائص إضافية ، ولا سيما عدم وجود أشرطة التمرير لعنصر الواجهة التمريرى. يمكنك أيضًا تعيين الخصائص من خلال GValue GValue val = G_VALUE_INIT;
g_value_init(&val, G_TYPE_BOOLEAN);
g_value_set_boolean(&val, TRUE);
gtk_container_child_set_property(GTK_CONTAINER(data->notebook), gr, "tab-expand", &val);
آلية التمرير: يتم تقسيم المقطع بالكامل على 100 ، ويتم حساب تغيير الجدول الزمني في وظيفة رد الاتصال. 100 مأخوذ من الأرقام gtk_adjustment_new (0،0،110،1،5،10) كـ 100 = 110-10.علاوة على ذلك ، حول وضع المعايير.
لتحديد معلمات النص ، نستخدم مكتبة pango لتعيين المعلمات. يسمح لك بحساب حجم النص بالبكسل لخط معين وحجمه الطبوغرافي وتصديره إلى طبقة القاهرة.
PangoLayout* get_width_height_of_text(char *text, char *font, float size, float *w, float *h)
{
GdkScreen *screen = gdk_screen_get_default();
PangoContext *context = gdk_pango_context_get_for_screen (screen);
PangoLayout *layout = pango_layout_new (context);
if(g_utf8_validate(text,-1,0))
{
pango_layout_set_text(layout,text,-1);
PangoFontDescription *desc=pango_font_description_new();
pango_font_description_set_family(desc,font);
pango_font_description_set_size(desc,size*1024);
pango_layout_set_font_description (layout, desc);
int width=0,height=0;
pango_layout_get_size(layout, &width, &height);
*w=(float) width/1024;
*h=(float) height/1024;
pango_font_description_free(desc);
}
else
{
printf(" UTF8\n");
}
return layout;
}
كما ترون ، يحسب البانجو الأحجام في وحداته الخاصة. أبرزت فئة منفصلةللنص ومعلماته.class text_layout
{
private:
int fontsize;
public:
GString *text;
GString *font;
PangoLayout *layout;
int width;
int height;
text_layout(char *text, char *font, int fontsize);
void change_text_font_fontsize(char *new_text, char *new_font, int new_fontsize);
~text_layout();
text_layout(float num, char *font, int fontsize);
};
تشكل معلمات المخطط فئة منفصلة:class graphic_parameters
{
private:
text_layout y_text=text_layout(" y","Liberation Serif", 14);
text_layout x_text=text_layout(" x","Liberation Serif", 14);
text_layout *number=0;
float max=0;
float min=0;
text_layout *max_=0;
text_layout *min_=0;
GtkAdjustment *adj;
GtkWidget *scrollbar;
float gap_x=25;
float gap_y=5;
void create_axes_and_xy_labels(void);
public:
cairo_t *cr;
float *massiv=0;
int len=0;
int count_in_display=0;
float multiplier_x=6;
int offset=0;
float x_null=0;
float y_null=0;
int pos=0;
float margin=16;
int callback_width;
int callback_height;
int widget_width;
int widget_height;
int scroll_height=0;
GtkWidget *eventbox;
GtkWidget *scrolledwindow;
GtkWidget *image_from_surface;
cairo_surface_t *surface;
graphic_parameters(int width, int height);
~graphic_parameters();
void resize_graphic(int new_width, int new_height);
void create_one_dimensional_graphic(float *massiv, int size);
void update_graphic(int offset);
void change_graphic_adj(void);
void create_vertical_line(void);
};
ينضم هذا الفصل إلى فئة التطبيق الرئيسية.class externals
{
public:
graphic_parameters *param;
externals();
};
class appdata : public externals
{
public:
char *glade_name=(char*)"window.glade";
GtkApplication *app;
GtkWidget *win;
GtkNotebook *notebook;
GtkMenuBar *menubar;
appdata();
};
بمعنى ، يتم إنشاء فئة الرسوم_المعلمات عند بدء تشغيل التطبيق ، وتتم تهيئة المحتوى حسب الضرورة عن طريق التحقق من NULL ، 0.كانت الصعوبة الرئيسية هي تصحيح جميع التحولات. حدث Segfaults 3 مرات: غاب مرتين FALSE في وظائف رد الاتصال ولم يتم تعيين الاختيار للخروج من الصفيف في وظيفة redraw. Qt لديها فئة QCustomPlot الجاهزة للتخطيط ، ولديها إمكانيات أكثر بكثير.
رابط إلى جيثب