所以,我的 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");
我希望當用戶點擊按鈕時,條目中的所有值都被傳遞給回呼函式,以便對資料進行一些操作。
我有:
g_signal_connect(btn, "clicked", G_CALLBACK(calculate), entries);
還有一個叫做calculate()的函式:
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]);
現在計算的函式是:
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)),但是如何獲取其他條目的文本?
uj5u.com熱心網友回復:
您正在搞亂傳遞給回呼函式的引數型別:
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 指標的陣列。
但是你告訴你的編譯器把它當作一個指向指標的指標:
void calculate(GtkWidget *btn, gpointer data){
double **values = (double **) data;
這表明記憶體布局非常不同。二維陣列與指向指標的指標不同。除此之外,您的陣列包含指標本身,而不是double值。
你需要的是這個:
void calculate(GtkWidget *btn, gpointer data){
GtkWidget*(*values)[10] = (GtkWidget*(*)[10])data;
...
這應該可以解決您正確處理條目的問題。
除此之外,您可能會遇到另一個問題。如果在entries呼叫回呼函式時陣列不再有效,則說明您進行了非法記憶體訪問,導致未定義行為。
您必須將該陣列設為靜態或全域。或者您必須確保執行初始化的函式在應用程式終止之前永遠不會回傳。
uj5u.com熱心網友回復:
用 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);
根據我從GtkButtonclicked 信號處理程式中了解到的, 的型別datashould match entries,即GtkEntry. 為什么,然后將其轉換為(double **)?
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/365036.html
