如何在GTK C程序中创建用户输入框和输出区域,类似于shell或终端?

huangapple go评论64阅读模式
英文:

How can I create a user input box and output area in a GTK C program, similar to a shell or terminal?

问题

You can use a GtkTextView widget to achieve the functionality you described. Here's the relevant code with the necessary modifications:

#include <gtk/gtk.h>

static GtkWidget *entry1 = NULL;
static GtkWidget *text_view = NULL;
static GtkTextBuffer *buffer = NULL;

void button_clicked(GtkWidget *widget, gpointer data)
{
    const gchar *entry_text1;
    entry_text1 = gtk_entry_get_text(GTK_ENTRY(entry1));
    
    // Get the current text from the text view
    GtkTextIter iter;
    gtk_text_buffer_get_end_iter(buffer, &iter);
    
    // Append the new text to the text view
    gtk_text_buffer_insert(buffer, &iter, entry_text1, -1);
    
    // Scroll to the end of the text view
    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text_view), gtk_text_buffer_get_insert(buffer), 0.0, FALSE, 0.0, 1.0);
}

void destroy(GtkWidget *widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc, char *argv[])
{
    gtk_init(&argc, &argv);
    GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(win), 680, 460);

    entry1 = gtk_entry_new();
    text_view = gtk_text_view_new();
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));

    GtkWidget *btn2 = gtk_button_new_with_label("Click Here2");

    GtkWidget *grd = gtk_grid_new();

    g_signal_connect(btn2, "clicked", G_CALLBACK(button_clicked), NULL);

    gtk_grid_attach(grd, entry1, 1, 1, 1, 1);
    gtk_grid_attach(grd, btn2, 2, 1, 1, 1);
    gtk_grid_attach(grd, text_view, 1, 2, 2, 1);

    gtk_container_add(GTK_CONTAINER(win), grd);
    gtk_container_set_border_width(GTK_CONTAINER(win), 20);
    g_signal_connect(win, "destroy", G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(win);
    gtk_main();
    return 0;
}

This code includes a GtkTextView widget (text_view) and a GtkTextBuffer (buffer) to manage the text inside the text view. When the button is clicked, it appends the text from the entry to the text view and scrolls to show the latest text, giving you a basic terminal-like behavior.

英文:

I am trying to make a shell-ish thing in C using GTK. I want to make a box where:

  1. the user types something
  2. the output appears in a box
  3. The output moves upwards and you can scroll (basically like a regular terminal.)

How would I go about doing this? Here is my code so far:

#include &lt;gtk/gtk.h&gt;
static GtkWidget *entry1 = 0;
void button_clicked(GtkWidget *widget,gpointer data)
{
    const gchar *entry_text1;
    entry_text1 = gtk_entry_get_text (GTK_ENTRY (entry1));
    g_print (&quot;%s\n&quot;, entry_text1);
}

void destroy(GtkWidget* widget, gpointer data)
{
    gtk_main_quit();
}
int main(int argc,char *argv[])
{
    gtk_init(&amp;argc,&amp;argv);
    GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (win), 680, 460);

    entry1 = gtk_entry_new();

    GtkWidget *btn2 = gtk_button_new_with_label(&quot;Click Here2&quot;);

    GtkWidget *grd = gtk_grid_new();


    g_signal_connect(btn2,&quot;clicked&quot;,G_CALLBACK(button_clicked),NULL);

    gtk_grid_attach(grd, entry1, 1,1,1,1);
    gtk_grid_attach(grd, btn2, 2,1,1,1);

    gtk_container_add(GTK_CONTAINER(win),grd);
    gtk_container_set_border_width(GTK_CONTAINER(win), 20);
    g_signal_connect(win, &quot;destroy&quot;,G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(win);
    gtk_main();
    return 0;
}

I have no clue what type of widget to use to do something like this.

答案1

得分: 1

我认为你应该使用 GtkScrolledWindow 来实现这个功能。例如:

#include &lt;gtk/gtk.h&gt;

// 用户在此输入内容。
static GtkWidget *input = NULL;

// 包含所有以前用户输入的文本的文本缓冲区。
static GtkTextBuffer *buffer = NULL;

// 当单击“userText”按钮时,将用户添加到输入的所有内容传输到文本区域。
void button_clicked(GtkWidget *widget, gpointer data)
{
    // 获取用户添加到输入的文本:
    const gchar *userText;
    userText = gtk_entry_get_text(GTK_ENTRY(input));
    
    // 在文本视图中插入(在末尾):
    GtkTextIter end; // 请注意,这是在堆栈上创建的!像往常一样传递指针不起作用。
                     // 请参阅:https://stackoverflow.com/questions/52182527/iterators-do-not-belong-to-their-assigned-text-buffer
    gtk_text_buffer_get_end_iter(buffer, &amp;end);
    
    gtk_text_buffer_insert(buffer, &amp;end, userText, -1);
    gtk_text_buffer_insert(buffer, &amp;end, &quot;\n&quot;, -1);
    
    // 清除用户输入以进行下一次输入:
    gtk_entry_set_text(GTK_ENTRY(input), &quot;&quot;);
}

void destroy(GtkWidget* widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc,char *argv[])
{
    gtk_init(&amp;argc,&amp;argv);
    
    GtkWidget *mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    input = gtk_entry_new();
    
    GtkWidget *send = gtk_button_new_with_label(&quot;Send&quot;);
 
    // 使用文本视图显示用户的过去输入(以终端方式)。我们将文本视图包装在GtkScrollmainWindowdow中,
    // 这使文本视图的内容可滚动:   
    GtkWidget *scrollWindow = gtk_scrolled_window_new(NULL, NULL);
    buffer = gtk_text_buffer_new(NULL);
    GtkWidget *textArea = gtk_text_view_new_with_buffer(buffer);
    gtk_container_add(GTK_CONTAINER(scrollWindow), textArea);

    g_signal_connect(send,&quot;clicked&quot;, G_CALLBACK(button_clicked), NULL);

    GtkWidget *layout = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(layout), scrollWindow, 1, 1, 2, 1);
    gtk_grid_attach(GTK_GRID(layout), input, 1, 2, 1, 1);
    gtk_grid_attach(GTK_GRID(layout), send, 2, 2, 1, 1);
    gtk_container_set_focus_child(GTK_CONTAINER(layout), input);

    gtk_container_add(GTK_CONTAINER(mainWindow),layout);
    gtk_container_set_border_width(GTK_CONTAINER(mainWindow), 20);
    g_signal_connect(mainWindow, &quot;destroy&quot;, G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(mainWindow);
    
    gtk_main();
    
    return 0;
}

这是在添加了"text 1"、"text 2"、"text 3"和"text 4"之后的样子:

如何在GTK C程序中创建用户输入框和输出区域,类似于shell或终端?

起初,看起来似乎没有滚动条(至少在我的设置中是这样),但将鼠标悬停在文本视图右侧会使它们出现:

如何在GTK C程序中创建用户输入框和输出区域,类似于shell或终端?

英文:

I think you should use GtkScrolledWindow to achieve this. For example:

#include &lt;gtk/gtk.h&gt;

// User adds contents to this entry.
static GtkWidget *input = NULL;

// The text buffer containing all previous user entries.
static GtkTextBuffer *buffer = NULL;

// When the &quot;userText&quot; button is clicked, all the user added to the
// entry is transfered to the text area.
void button_clicked(GtkWidget *widget, gpointer data)
{
    // Get the text added to the entry by the user:
    const gchar *userText;
    userText = gtk_entry_get_text(GTK_ENTRY(input));
    
    // Insert in the text view (at the end):
    GtkTextIter end; // Notice how this is created on the stack! Passing a pointer as usual is not working.
                     // See : https://stackoverflow.com/questions/52182527/iterators-do-not-belong-to-their-assigned-text-buffer
    gtk_text_buffer_get_end_iter(buffer, &amp;end);
    
    gtk_text_buffer_insert(buffer, &amp;end, userText, -1);
    gtk_text_buffer_insert(buffer, &amp;end, &quot;\n&quot;, -1);
    
    // Clear the user input entry for the next input:
    gtk_entry_set_text(GTK_ENTRY(input), &quot;&quot;);
}

void destroy(GtkWidget* widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc,char *argv[])
{
    gtk_init(&amp;argc,&amp;argv);
    
    GtkWidget *mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    input = gtk_entry_new();
    
    GtkWidget *send = gtk_button_new_with_label(&quot;Send&quot;);
 
    // A text view is used to show the user&#39;s past input (in terminal
    // fashion). We wrap the text view in a GtkScrollmainWindowdow, which
    // makes the text view&#39;s content scrollable:   
    GtkWidget *scrollWindow = gtk_scrolled_window_new(NULL, NULL);
    buffer = gtk_text_buffer_new(NULL);
    GtkWidget *textArea = gtk_text_view_new_with_buffer(buffer);
    gtk_container_add(GTK_CONTAINER(scrollWindow), textArea);

    g_signal_connect(send,&quot;clicked&quot;, G_CALLBACK(button_clicked), NULL);

    GtkWidget *layout = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(layout), scrollWindow, 1, 1, 2, 1);
    gtk_grid_attach(GTK_GRID(layout), input, 1, 2, 1, 1);
    gtk_grid_attach(GTK_GRID(layout), send, 2, 2, 1, 1);
    gtk_container_set_focus_child(GTK_CONTAINER(layout), input);

    gtk_container_add(GTK_CONTAINER(mainWindow),layout);
    gtk_container_set_border_width(GTK_CONTAINER(mainWindow), 20);
    g_signal_connect(mainWindow, &quot;destroy&quot;, G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(mainWindow);
    
    gtk_main();
    
    return 0;
}

Here is what it looks like after having added "text 1", "text 2", "text 3" and "text 4", in that order:

如何在GTK C程序中创建用户输入框和输出区域,类似于shell或终端?

At first, it seems like there are no scrollbars (at least on my setup), but hovering the mouse on the right side of the text view makes them appear:

如何在GTK C程序中创建用户输入框和输出区域,类似于shell或终端?

huangapple
  • 本文由 发表于 2023年5月26日 16:45:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76339147.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定