GTK+基本操作加图形化计算器实现

1.GTK+简介

Linux下大多数的开发都是基于字符界面的,但是在Linux下也可以开发出美观大方的图形界面,其中较为常用的是QtGTK+;
为什么我们要在这里说GTK+呢?
因为GTK+使用C语言作为开发语言,GTK+是开放源代码而且免费的,简单易用,执行效率高,Linux的桌面环境GNOME就是建立在GTK+的基础上;

2.GTK+的简单操作

2.1.Deeping安装GTK+

sudo apt-get install libgtk-3-dev

2.2如何编译写好的程序

首先使用GTK+要加上头文件

#include <gtk/gtk.h>

然后在编译时加上

gcc gtk.c `pkg-config --libs --cflags gtk±2.0`

2.3创建一个简单的窗口

#include <stdio.h>
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    // 设置窗口
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    // 设置标题
    gtk_window_set_title((GtkWindow *)window, "Hello World!");
    // 设置窗口大小
    gtk_widget_set_size_request(window, 400, 400);
    // FALSE设置为不可伸缩,默认可伸缩
    gtk_window_set_resizable((GtkWindow *)window, FALSE);
    // 窗口在显示器位置,第二个参数GTK_WIN_POS_...4种NONE不固定 CENTER居中 MOUSE鼠标位置CENTER_ALWAYS总是居中
    gtk_window_set_position((GtkWindow *)window, GTK_WIN_POS_MOUSE);
    gtk_widget_show(window);

    
    gtk_main();
    return 0;
}

在这里插入图片描述

运行上面的程序就会出现一个这样的界面,但是这个界面点击右上角叉号后窗口是关闭了,但是程序并没有结束运行,需要我们ctrl+c手动结束;
所以我们要用到一个函数,设置点击了这个按钮以后产生的反应;
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
这里的gtk_main_quit就是点击以后产生的回调函数,这个就是用来终止gtk_main的循环的;
gtk_main()就相当于while(1)如果不这样,那我们的创建的窗口闪一下就没了;

2.4创建一个按钮,把按钮加入到窗口中

#include <stdio.h>
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
    // 窗口    
    GtkWidget *window;
    // 按钮
    GtkWidget *button;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window, 800, 800);
    // 创建按钮
    button = gtk_button_new_with_label("Hello World");
    // 添加按钮到window
    gtk_container_add((GtkContainer *)window, button);
    // 获取按钮的内容
    const char *result = gtk_button_get_label((GtkButton *)button);
    printf("result = %s\n", result);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

GTK+中我们创建的控件一定要记得加入到窗口中,不然最后调用
gtk_widget_show_all(window)的时候就不会显示了;
如果不设置控件的大小那么我们创建的这个按钮就会布满我们的整个窗口;
在这里插入图片描述
就像这样;

2.5GTK+预设的数据类型及回调函数

这里不说太多,gchar什么和C语言的char没有什么区别;
我们来说一下gpointer;
这个相当于C语言的void *这个用在设置回调函数的第二个参数;当我们按下一个按钮以后必然想要产生一些效果;这个时候就需要回调函数;
void callback(GtkButton *button, gpointer arg)
这是回调函数的类型;
g_signal_connect(控件, 操作, 回调函数, 传入的参数gpointer arg)

#include <stdio.h>
#include <gtk/gtk.h>

// 回调函数类型,gpointer 相当于void *
void fun(GtkButton *button, gpointer arg)
{
    printf("hello world!!\n");
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *button;
    int a = 8;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window, 600, 600);
    button = gtk_button_new_with_label("Hello!");
    gtk_container_add((GtkContainer *)window, button);
    // 调函数第二个参数是操作名称, 第三个参数是掉的函数名这里的clicked是点击,最后一个参数是传递的参数
    g_signal_connect(button, "clicked", G_CALLBACK(fun), NULL);
    // 点击关闭退出gtk_main_quit是库里用来退出gtk_main的
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show_all(window);

    gtk_main();
    return 0;
}

2.6布局

2.6.1水平布局

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *hbox;
    GtkWidget *button;
    GtkWidget *button1;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title((GtkWindow *)window, "Hello!");
    gtk_widget_set_size_request(window, 600, 600);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    button = gtk_button_new_with_label("hello");
    button1 = gtk_button_new_with_label("world");
    // 创建一个水平布局容器,第二个参数是间距
    hbox = gtk_hbox_new(TRUE, 5);
    // 创建一个标签
    GtkWidget *label = gtk_label_new("1");
    GtkWidget *label1 = gtk_label_new("2");
    // 先把hbox添加到window里
    gtk_container_add((GtkContainer *)window, hbox);
    // 再把两个按钮添加到水平容器hbox中
    gtk_container_add((GtkContainer *)hbox, button);
    gtk_container_add((GtkContainer *)hbox, button1);
    gtk_container_add((GtkContainer *)hbox, label);
    gtk_container_add((GtkContainer *)hbox, label1);
    gtk_widget_show_all(window);

    gtk_main();
    return 0;
}

当我们创建好一个布局时我们要将我们创建好的布局加入到窗口中,然后再将按钮添加到布局里;

2.6.2表格布局

把按钮加入到表格布局里用到的函数就不再是gtk_container_add()了;而是
gtk_table_attach_defaults((GtkTable *)table, button, 0, 1, 0, 1);
后面的4个数字分别代表,左右上下;
在这里插入图片描述
如果我们要把这个放在第一个方框,后面的4个数字就是0, 1, 0, 1;

2.6.3综合布局和行编辑

我们一般不会只简单使用一个布局通常我们要把几个布局合在一起使用,这里我们用一个小项目来体会一下;
在这里插入图片描述
当我们点击add时加一个1点击del时删除文本框里的内容点击print时打印文本框里的内容;
这里我们先来说这个行编辑;
创建一个行编辑:
GtkWidget *entry = gtk_entry_new();
获取行编辑里的内容
const gchar *str = gtk_entry_get_text(entry);
注意这里返回是const gchar *所以当我们想向行编辑里面添加东西的时候我们不能单纯的使用strcat函数

 GtkEntry *entry = (GtkEntry *)arg;
 const char *str = gtk_entry_get_text(entry);
 char text[1024];
 strcpy(text, str);
 strcat(text, "1");
 gtk_entry_set_text(entry, text);

这个小项目的源代码在这里,可以自己先动手写一下;

#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>

void add(GtkButton *button, gpointer arg)
{
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    char text[1024];
    strcpy(text, str);
    strcat(text, "1");
    gtk_entry_set_text(entry, text);
}

void del(GtkButton *button, gpointer arg)
{
    GtkEntry *entry = (GtkEntry *)arg;
    gtk_entry_set_text(entry, "");
}

void print(GtkButton *button, gpointer arg)
{
    GtkEntry *entry = (GtkEntry *)arg;
    const gchar *str = gtk_entry_get_text(entry);
    printf("str = %s\n", str);
}

int main(int argc, char *argv[]) 
{
    gtk_init(&argc, &argv);
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title((GtkWindow *)window, "hello");
    gtk_widget_set_size_request(window, 400, 600);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    GtkWidget *button_add = gtk_button_new_with_label("add");
    GtkWidget *button_del = gtk_button_new_with_label("del");
    GtkWidget *button_print = gtk_button_new_with_label("print");
    // 垂直布局
    GtkWidget *vbox = gtk_vbox_new(TRUE, 5);
    // 水平布局
    GtkWidget *hbox = gtk_hbox_new(TRUE, 5);
    // 行编辑
    GtkWidget *entry = gtk_entry_new();
    gtk_container_add((GtkContainer *)window, vbox);
    gtk_container_add((GtkContainer *)vbox, entry);    
    gtk_container_add((GtkContainer *)vbox, hbox);
    gtk_container_add((GtkContainer *)hbox, button_add);    
    gtk_container_add((GtkContainer *)hbox, button_del);
    gtk_container_add((GtkContainer *)vbox, button_print);
    g_signal_connect(button_add, "clicked", G_CALLBACK(add), entry);
    g_signal_connect(button_del, "clicked", G_CALLBACK(del), entry);
    g_signal_connect(button_print, "clicked", G_CALLBACK(print), entry);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

3.图形化计算器

如果把上面那个小项目写出来那么这个图形化的计算器应该很简单;就是按钮多了点,回调函数多了点,这里我们直接放源代码
在这里插入图片描述

// 计算器

#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <math.h>
#include <stdlib.h>

#define EMPTY 0
#define NOEMPTY 1
#define MORE 1
#define LESS 0

// 运算数栈
typedef struct {
    double num[1024];
    int top;
} Num;

// 操作符栈
typedef struct {
    char c[1024];
    int top;
} Char;

/* --------------------------------- */

Num lnum;
Char lchar;

// 求次方的函数
double power(int n) 
{
    double a = 1;
    if (n == 0) {
        return 1;
    }
    n = n * (-1);
    if (n > 0) {
        for (int i = 0; i < n; i++) {
             a /= 10;
        }
        return a;
    }
}

// 判断栈不是为空
int Empty(int num) {
    if (num == -1) {
        return EMPTY;
    } else {
        return NOEMPTY;
    }
}

// 操作数入栈
void PopNum(Num *lnum, double num)
{
    lnum->num[++lnum->top] = num;
}

// 操作数出栈
void PushNum(Num *lnum, double  *num)
{
    *num = lnum->num[lnum->top--];
}

// 运算符入栈
void PopChar(Char *lchar, char x)
{
    lchar->c[++lchar->top] = x;
}

// 运算符出栈
void PushChar(Char *lchar, char *x)
{
    *x = lchar->c[lchar->top--];
}

// 比较运算符优先级
int Judge(char a, char b)
{
    switch(a) {
        case '+':
                if (b == '+' || b == '-') {
                    return MORE;
                } else {
                    return LESS;
                }
        case '-':
                if (b == '-' || b == '+') {
                    return MORE;
                } else {
                    return LESS;
                }
        case '*':
        case '/':
                return MORE;
        default:break;
    }
}

void Zero(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "0");
    gtk_entry_set_text(entry, temp);
}

void One(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "1");
    gtk_entry_set_text(entry, temp);
}

void Two(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "2");
    gtk_entry_set_text(entry, temp);
}

void Three(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "3");
    gtk_entry_set_text(entry, temp);
}

void Four(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "4");
    gtk_entry_set_text(entry, temp);
}

void Five(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "5");
    gtk_entry_set_text(entry, temp);
}

void Six(GtkButton *button, gpointer arg) 
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "6");
    gtk_entry_set_text(entry, temp);
}

void Seven(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "7");
    gtk_entry_set_text(entry, temp);
}

void Eight(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "8");
    gtk_entry_set_text(entry, temp);
}

void Nine(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "9");
    gtk_entry_set_text(entry, temp);
}

void Point(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, ".");
    gtk_entry_set_text(entry, temp);
}

void Add(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "+");
    gtk_entry_set_text(entry, temp);
}

void Jian(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "-");
    gtk_entry_set_text(entry, temp);
}

void Cheng(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "*");
    gtk_entry_set_text(entry, temp);
}

void Chu(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    strcat(temp, "/");
    gtk_entry_set_text(entry, temp);
}

void Clear(GtkButton *button, gpointer arg)
{
    GtkEntry *entry = (GtkEntry *)arg;
    gtk_entry_set_text(entry, "");
}

void Del(GtkButton *button, gpointer arg)
{
    char temp[1024];
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    strcpy(temp, str);
    int k = strlen(temp);
    if (k > 0) {
        temp[k-1] = '\0';
        gtk_entry_set_text(entry, temp);
    }
}

// 获取操作数栈顶元素
void GetTop(Char *lchar, char *x)
{
    *x = lchar->c[lchar->top];
}


void Result(GtkButton *button, gpointer *arg)
{
    GtkEntry *entry = (GtkEntry *)arg;
    const char *str = gtk_entry_get_text(entry);
    char temp[100];
    double a = 0;
    double b = 0;
    char x;
    int j = -1;
    int k = strlen(str);
    for (int i = 0; i < k; i++) {
        if (str[i] >= '0' && str[i] <= '9') {
            a = b = 0;
            while (i < k && str[i] != '+' && str[i] != '-' && str[i] != '*' && str[i] != '/' && str[i] != '.') {
                a = ((int)str[i] - 48) + a * 10;
                i++;
            }
            if (i < k && str[i] == '.') {
                i++;
                while (str[i] != '+' && str[i] != '-' && str[i] != '*' && str[i] != '/' && i < k) {
                    b = ((int)str[i] - 48)  * power(j) + b;
                    j--;
                    i++;
                }
            }
            i--;
            a += b;
            PopNum(&lnum, a);
            a = 0;
            b = 0;
            j = -1;
        } else {
            if (Empty(lchar.top) == EMPTY) {
                PopChar(&lchar, str[i]);
            } else {
                GetTop(&lchar, &x);
                while (Judge(x, str[i]) == MORE) {
                    PushChar(&lchar, &x);
                    PushNum(&lnum, &b);
                    PushNum(&lnum, &a);
                    switch(x) {
                        case '+':
                                a += b;
                                break;
                        case '-':
                                a -= b;
                                break;
                        case '*':
                                a *= b;
                                break;
                        case '/':
                                a /= b;
                                break;
                        default:break;
                    }
                    PopNum(&lnum, a);
                    a = 0;
                    b = 0;
                    if (Empty(lchar.top) == EMPTY) {
                        break;
                    }
                    GetTop(&lchar, &x);
                }
                PopChar(&lchar, str[i]);
            }
        }
    }
    PushChar(&lchar, &x);
    PushNum(&lnum, &b);
    PushNum(&lnum, &a);
        switch(x) {
            case '+':
                    a += b;
                    break;
            case '-':
                    a -= b;
                    break;
            case '*':
                    a *= b;
                    break;
            case '/':
                    a /= b;
                    break;
            default:break;
    }
    lchar.top = -1;
    lnum.top = -1;
    sprintf(temp, "%lf", a);
    gtk_entry_set_text(entry, temp);
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    // 数据结构初始化
    lnum.top = -1;
    lchar.top = -1;
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title((GtkWindow *)window, "计算器");
    gtk_widget_set_size_request(window, 400, 600);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    // 垂直布局
    GtkWidget *vbox = gtk_vbox_new(TRUE, 10);
    // 表格布局
    GtkWidget *table = gtk_table_new(5, 4, TRUE);
    // 行编辑
    GtkWidget *entry = gtk_entry_new();
    // 将垂直布局加入到window中
    gtk_container_add((GtkContainer *)window, vbox);
    // 将行编辑添加到垂直布局里
    gtk_container_add((GtkContainer *)vbox, entry);
    // 将表格布局添加到垂直布局里
    gtk_container_add((GtkContainer *)vbox, table);
    // 设置按钮
    GtkWidget *button_clear = gtk_button_new_with_label("C");
    GtkWidget *button_del = gtk_button_new_with_label("DEL");
    GtkWidget *button_division = gtk_button_new_with_label("/");
    GtkWidget *button_multiplication = gtk_button_new_with_label("*");
    GtkWidget *button_subtraction = gtk_button_new_with_label("-");
    GtkWidget *button_add = gtk_button_new_with_label("+");
    GtkWidget *button_result = gtk_button_new_with_label("=");
    GtkWidget *button_point = gtk_button_new_with_label(".");
    GtkWidget *button1 = gtk_button_new_with_label("1");
    GtkWidget *button2 = gtk_button_new_with_label("2");
    GtkWidget *button3 = gtk_button_new_with_label("3");
    GtkWidget *button4 = gtk_button_new_with_label("4");
    GtkWidget *button5 = gtk_button_new_with_label("5");
    GtkWidget *button6 = gtk_button_new_with_label("6");
    GtkWidget *button7 = gtk_button_new_with_label("7");  
    GtkWidget *button8 = gtk_button_new_with_label("8");  
    GtkWidget *button9 = gtk_button_new_with_label("9");  
    GtkWidget *button0 = gtk_button_new_with_label("0");
    // 将上面的按钮添加到表格布局中
    gtk_table_attach_defaults((GtkTable *)table, button_clear, 0, 1, 0, 1);
    gtk_table_attach_defaults((GtkTable *)table, button_del, 1, 2, 0, 1);
    gtk_table_attach_defaults((GtkTable *)table, button_division, 2, 3, 0, 1);
    gtk_table_attach_defaults((GtkTable *)table, button_multiplication, 3, 4, 0, 1);
    gtk_table_attach_defaults((GtkTable *)table, button_subtraction, 3, 4, 1, 2);
    gtk_table_attach_defaults((GtkTable *)table, button_add, 3, 4, 2, 3);
    gtk_table_attach_defaults((GtkTable *)table, button_result, 3, 4, 3, 5);
    gtk_table_attach_defaults((GtkTable *)table, button1, 0, 1, 3, 4);
    gtk_table_attach_defaults((GtkTable *)table, button2, 1, 2, 3, 4);
    gtk_table_attach_defaults((GtkTable *)table, button3, 2, 3, 3, 4);
    gtk_table_attach_defaults((GtkTable *)table, button4, 0, 1, 2, 3);
    gtk_table_attach_defaults((GtkTable *)table, button5, 1, 2, 2, 3);
    gtk_table_attach_defaults((GtkTable *)table, button6, 2, 3, 2, 3);
    gtk_table_attach_defaults((GtkTable *)table, button7, 0, 1, 1, 2);
    gtk_table_attach_defaults((GtkTable *)table, button8, 1, 2, 1, 2);
    gtk_table_attach_defaults((GtkTable *)table, button9, 2, 3, 1, 2);
    gtk_table_attach_defaults((GtkTable *)table, button0, 0, 2, 4, 5);
    gtk_table_attach_defaults((GtkTable *)table, button_point, 2, 3, 4, 5);
    // 设置回调函数
    g_signal_connect(button_add, "clicked", G_CALLBACK(Add), entry);
    g_signal_connect(button_clear, "clicked", G_CALLBACK(Clear), entry);
    g_signal_connect(button_del, "clicked", G_CALLBACK(Del), entry);
    g_signal_connect(button_division, "clicked", G_CALLBACK(Chu), entry);
    g_signal_connect(button_multiplication, "clicked", G_CALLBACK(Cheng), entry);
    g_signal_connect(button_subtraction, "clicked", G_CALLBACK(Jian), entry);
    g_signal_connect(button_point, "clicked", G_CALLBACK(Point), entry);
    g_signal_connect(button_result, "clicked", G_CALLBACK(Result), entry);
    g_signal_connect(button1, "clicked", G_CALLBACK(One), entry);
    g_signal_connect(button2, "clicked", G_CALLBACK(Two), entry);
    g_signal_connect(button3, "clicked", G_CALLBACK(Three), entry);
    g_signal_connect(button4, "clicked", G_CALLBACK(Four), entry);
    g_signal_connect(button5, "clicked", G_CALLBACK(Five), entry);
    g_signal_connect(button6, "clicked", G_CALLBACK(Six), entry);
    g_signal_connect(button7, "clicked", G_CALLBACK(Seven), entry);
    g_signal_connect(button8, "clicked", G_CALLBACK(Eight), entry);
    g_signal_connect(button9, "clicked", G_CALLBACK(Nine), entry);
    g_signal_connect(button0, "clicked", G_CALLBACK(Zero), entry);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

关于如何放大控件中的字体和行编辑中的字体,我也还在学习,查阅了很多百度也没有查到,如果大家知道欢迎给我评论留言;

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值