簡體   English   中英

如何在 C 的 GTK+ 單按鈕單擊事件中傳遞多個小部件

[英]How to pass multiple widgets in a GTK+ single button click event in C

因此,我的 GTK 應用程序的二維數組中有許多條目,如下所示:

GtkWidget *entries[10][10];
for(int i = 0; i < 10; i++){
        for(int j = 0; j < 10; j++){
                entries[i][j] = gtk_entry_new();
        }
}

還有一個按鈕:

GtkWidget *btn;
btn = gtk_button_new_with_label("Calculate");

我希望,當用戶單擊按鈕時,條目中的所有值都將傳遞給回調 function 以便對數據進行一些操作。

我有:

g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries);

還有一個名為calculate()的function:

void calculate(GtkWidget *btn, gpointer data){
        double **values = (double **) data;
    
        for(int i = 0; i < 10; i++){
                for(int j = 0; j < 10; j++){
                    printf("%f ", gtk_entry_get_text(GTK_ENTRY(values[i][j])));
                }
        
                printf("\n");
        }
}

它的名字暗示將要進行計算。 事實上,我打算開發代碼來做到這一點,但在此之前我需要獲取條目中的數據。

為什么我沒有成功獲取數據?

[更新]

我改變了g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries); g_signal_connect(btn, "clicked", G_CALLBACK(calculate), &entries[0][0]);

現在計算的 function 是:

void calculate(GtkWidget* btn, gpointer *data){ 
    GtkWidget **values = (GtkWidget **) data;
    
    for(int i = 0; i < 10; i++){
        for(int j = 0; j < 10; j++){
            printf("%s\n", gtk_entry_get_text(GTK_ENTRY(*(values+i) + j)));
        }
    }
}

我使用gtk_entry_get_text(GTK_ENTRY(*values))成功獲取了第一個條目的文本,但是如何獲取其他條目的文本?

您正在弄亂傳遞給回調 function 的參數類型:

GtkWidget *entries[10][10];
for(int i = 0; i < 10; i++){
        for(int j = 0; j < 10; j++){
                entries[i][j] = gtk_entry_new();
        }
}
...

g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries);

這定義了一個 10*10 指針的數組。

但是然后您告訴編譯器將 is 視為指向指針的指針:

void calculate(GtkWidget *btn, gpointer data){
        double **values = (double **) data;

這表明 memory 布局非常不同。 二維數組與指向指針的指針不同。 除此之外,您的數組本身還包含指針。

你需要的是這樣的:

void calculate(GtkWidget *btn, gpointer data){
       GtkWidget*(*values)[10] = (GtkWidget*(*)[10])data;
...

這應該可以解決您正確處理條目的問題。

除此之外,您可能會遇到另一個問題。 如果在調用回調 function 時數組entries不再有效,則您有非法的 memory 訪問導致未定義的行為。

您必須使該數組 static 或全局數組。 或者您必須確保執行初始化的 function 在應用程序終止之前永遠不會返回。

在 C++ 中解決

我不是 C Gtk+ 用戶,但我能夠使其在 Gtkmm 3.24(我更熟悉)下工作。 這是我的程序,應該可以翻譯成 C 語言:

#include <array>
#include <iostream>
#include <string>

#include <gtkmm.h>

class MainWindow : public Gtk::ApplicationWindow
{

public:

    MainWindow();

private:

    Gtk::Grid m_layout;

    Gtk::Button m_button;
    std::array<Gtk::Entry, 4> m_entries;

};

MainWindow::MainWindow()
: m_button{"Print entries content"}
{
    // Configuring entries:
    size_t count = 0u;
    for(auto& entry : m_entries)
    {
        entry.set_text("Entry #" + std::to_string(count));
        ++count;
    }

    // Configuring the button handler:
    m_button.signal_clicked().connect(
        [this]()
        {
            for(const auto& entry : m_entries)
            {
                std::cout << "Entry text : " << entry.get_text() << std::endl;
            }
        }
    );

    // Configuring window layout:
    m_layout.attach(m_entries[0], 0, 0, 1, 1);
    m_layout.attach(m_entries[1], 1, 0, 1, 1);
    m_layout.attach(m_entries[2], 0, 1, 1, 1);
    m_layout.attach(m_entries[3], 1, 1, 1, 1);
    m_layout.attach(m_button, 0, 2, 2, 1);

    // Adding the layout to the window:
    add(m_layout);
}

int main(int argc, char *argv[])
{
    std::cout << "Gtk(mm) version : " << gtk_get_major_version() << "."
                                      << gtk_get_minor_version() << "."
                                      << gtk_get_micro_version() << std::endl;

    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
  
    MainWindow window;
    window.show_all();
  
    return app->run(window);
}

順便說一句,請注意這是我理解您的問題的(最小)簡化版本。

關於您的代碼片段的其他說明

查看您的代碼,我看到了這一行:

double **values = (double **) data;

但是,當您連接時,您有:

g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries);

根據我從GtkButton clicked 信號處理程序的理解, data的類型應該匹配entries ,它是GtkEntry的表。 為什么,然后將其轉換為(double **)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM