1 简介
该计算器利用GTK3.0实现加减乘除计算,但是目前仅限于两项数据的计算,尚未实现多项计算,后续完善.
2 c源码
#include<gtk/gtk.h>
#include<string.h>
GtkWidget *input_entry, *output_entry;
struct calculator_widget{
/*
* 计算器控件
*/
GtkWidget *window;
GtkWidget *input_label, *output_label;
// GtkWidget *input_entry, *output_entry;
GtkWidget *button0, *button1, *button2, *button3, *button4;
GtkWidget *button5, *button6, *button7, *button8, *button9;
GtkWidget *add_button, *minus_button, *multiply_button, *divide_button;
GtkWidget *equal_button, *delete_button;
GtkWidget *hbox0, *hbox1, *hbox2, *hbox3, *hbox4, *hbox5, *hbox6, *hbox7;
GtkWidget *vbox;
GtkWidget *quit_button;
GtkWidget *copyright;
};
//保存计算器数据
char input_buf[50] = {0};
char output_buf[50] = {0};
void calculator_callback(GtkButton *button, gpointer data){
/*
* 回调函数: 加减乘除运算
*/
// 获取按钮数据
const gchar *txt = gtk_button_get_label(button);
if(strcmp("c", txt) == 0){
//清空数据
gtk_entry_set_text(GTK_ENTRY(input_entry), "");
gtk_entry_set_text(GTK_ENTRY(output_entry), "");
int i;
//清空输入数据
for(i=0;i<strlen(input_buf);i++){
input_buf[i] = 0;
}
}
else{
int a=0, b=0;
// char buf[50] = {0};
char c;
// 计算
if(strcmp("=", txt) == 0){
//数据拆包
int data_l;
data_l = strlen(input_buf);
sscanf(input_buf, "%d%c%d", &a, &c, &b);
printf("a=%d, c=%c, d=%d\n", a,c,b);
if('+' == c){
sprintf(output_buf, "%d", a+b);
}else if('-' == c){
sprintf(output_buf, "%d", a-b);
}else if('*' == c){
sprintf(output_buf, "%d", a*b);
}else if('/' == c){
sprintf(output_buf, "%d", a/b);
}
gtk_entry_set_text(GTK_ENTRY(output_entry), output_buf);
}else{
//内容追加
strcat(input_buf, txt);
gtk_entry_set_text(GTK_ENTRY(input_entry), input_buf);
}
}
}
void calculator_structure(GtkApplication *app, gpointer data){
/*计算器布局*/
struct calculator_widget cal_wgt;
// 新建窗口
cal_wgt.window = gtk_application_window_new(app);
// 设置窗口属性
gtk_window_set_position(GTK_WINDOW(cal_wgt.window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(cal_wgt.window), "计算器v0.0");
// gtk_window_set_default_size(GTK_WINDOW(cal_wgt.window), 400, 400);
gtk_container_set_border_width(GTK_CONTAINER(cal_wgt.window), 10);
// 文本框
cal_wgt.input_label = gtk_label_new("计算:");
input_entry = gtk_entry_new();
cal_wgt.output_label = gtk_label_new("结果:");
output_entry = gtk_entry_new();
// 禁止编辑
gtk_editable_set_editable(GTK_EDITABLE(input_entry), FALSE);
gtk_editable_set_editable(GTK_EDITABLE(output_entry), FALSE);
//数字按钮
cal_wgt.button0 = gtk_button_new_with_label("0");
cal_wgt.button1 = gtk_button_new_with_label("1");
cal_wgt.button2 = gtk_button_new_with_label("2");
cal_wgt.button3 = gtk_button_new_with_label("3");
cal_wgt.button4 = gtk_button_new_with_label("4");
cal_wgt.button5 = gtk_button_new_with_label("5");
cal_wgt.button6 = gtk_button_new_with_label("6");
cal_wgt.button7 = gtk_button_new_with_label("7");
cal_wgt.button8 = gtk_button_new_with_label("8");
cal_wgt.button9 = gtk_button_new_with_label("9");
// 运算按钮
cal_wgt.add_button = gtk_button_new_with_label("+");
cal_wgt.minus_button = gtk_button_new_with_label("-");
cal_wgt.multiply_button = gtk_button_new_with_label("*");
cal_wgt.divide_button = gtk_button_new_with_label("/");
cal_wgt.equal_button = gtk_button_new_with_label("=");
cal_wgt.delete_button = gtk_button_new_with_label("c");
// 退出
cal_wgt.quit_button = gtk_button_new_with_label("退出");
cal_wgt.copyright = gtk_label_new("©2019 xdq");
// 新建box
cal_wgt.hbox0 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox3 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox4 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox5 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox6 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.hbox7 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
cal_wgt.vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
//水平box:按钮布局
//输入框
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox0), cal_wgt.input_label, TRUE, FALSE, 8);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox0), input_entry, TRUE, FALSE, 8);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox1), cal_wgt.output_label, TRUE, FALSE, 8);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox1), output_entry, TRUE, FALSE, 8);
// 第一行数据
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox2), cal_wgt.button7, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox2), cal_wgt.button8, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox2), cal_wgt.button9, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox2), cal_wgt.delete_button, TRUE, FALSE, 2);
//第二行数据
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox3), cal_wgt.button4, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox3), cal_wgt.button5, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox3), cal_wgt.button6, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox3), cal_wgt.multiply_button, TRUE, FALSE, 2);
//第三行数据
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox4), cal_wgt.button1, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox4), cal_wgt.button2, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox4), cal_wgt.button3, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox4), cal_wgt.divide_button, TRUE, FALSE, 2);
//第四行数据
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox5), cal_wgt.button0, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox5), cal_wgt.add_button, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox5), cal_wgt.minus_button, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox5), cal_wgt.equal_button, TRUE, FALSE, 2);
// 第五行动作
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox6), cal_wgt.quit_button, TRUE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.hbox7), cal_wgt.copyright, TRUE, FALSE, 2);
//垂直box:区域布局
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox0, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox1, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox2, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox3, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox4, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox5, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox6, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(cal_wgt.vbox), cal_wgt.hbox7, FALSE, FALSE, 2);
//信号回调
g_signal_connect(cal_wgt.button0, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button1, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button2, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button3, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button4, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button5, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button6, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button7, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button8, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.button9, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.add_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.minus_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.multiply_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.divide_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.equal_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect(cal_wgt.delete_button, "pressed", G_CALLBACK(calculator_callback), NULL);
g_signal_connect_swapped(cal_wgt.quit_button, "clicked", G_CALLBACK(gtk_widget_destroy), cal_wgt.window);
// 控件添加到窗口
gtk_container_add(GTK_CONTAINER(cal_wgt.window), cal_wgt.vbox);
gtk_widget_show_all(cal_wgt.window);
}
int main(int argc, char **argv){
GtkApplication *app;
app = gtk_application_new("org.calculator", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(calculator_structure), NULL);
g_application_run(G_APPLICATION(app), argc, argv);
return 0;
}
3 结果
4 小结
(1)该简易计算器熟悉了按钮,输入框,盒子的使用方法;
(2) 创建窗口,每个窗口只能容纳一个容器,在容器中进行各种构件的布局;
(3) 计算器实现了两项式的加减乘除,多项式计算待后续更新;
【参考文献】
[1]https://developer.gnome.org/gtk3/stable/index.html
[2]https://blog.csdn.net/xiangnideye1/article/details/44501635