Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[GTK+] 3 problemy.

Ostatnio zmodyfikowano 2012-07-03 11:55
Autor Wiadomość
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-06-16 16:41:07
Pierwsze 3 problemy rozwiązane. Dzięki. Może jednak ktoś mi podpowie z tym wczytywaniem tekstu?
Jak zrobić, żeby po kliknięciu na przycisk wyświetlić w oknie nową zawartość? Usuwać starą i dać nową?
Próbowałem trochę ale nic nie działa.
P-58565
m4tx
» 2012-06-16 16:41:39
Może dasz kod? :)
P-58566
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-06-16 16:45:00
Aktualna wersja :P
C/C++
#include<gtk/gtk.h>

void dalej( GtkWidget * okno, GtkWidget * obraz, GtkWidget * kontener2, GtkWidget * okno2 )
{
    okno2 = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    kontener2 = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno2 ), kontener2 );
    obraz = gtk_image_new_from_file( "obraz.jpg" );
    gtk_container_add( GTK_CONTAINER( kontener2 ), obraz );
}


int main( int argc, char * argv[] )
{
    GtkWidget * okno;
    GtkWidget * ptxt;
    GtkWidget * napis;
    GtkWidget * kontener;
    GtkWidget * linia;
    GtkWidget * napis2;
    GtkWidget * obraz;
    GtkWidget * przycisk;
    GtkWidget * kontener2;
    GtkWidget * okno2;
   
    gtk_init( & argc, & argv );
    okno = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_title( GTK_WINDOW( okno ), "Kurs GTK+" );
    gtk_window_set_position( GTK_WINDOW( okno ), GTK_WIN_POS_CENTER );
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 150 );
    //gtk_window_set_resizable( GTK_WINDOW( okno ), FALSE );
   
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 200 );
   
    przycisk = gtk_button_new_with_label( "dalej" );
    gtk_widget_set_size_request( przycisk, 10, 20 );
   
   
    kontener = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno ), kontener );
   
    //obraz = gtk_image_new_from_file("obraz.gif");
    //gtk_container_add(GTK_CONTAINER(kontener), obraz);
   
    linia = gtk_hseparator_new();
   
    char * zm = "<tt><u>Wpisz</u> swoje</tt><span bgcolor='#00FF00'> imie</span>"; // podanie i sformatowanie tekstu
    gtk_box_pack_start( GTK_BOX( kontener ), linia, FALSE, TRUE, 17 );
   
    napis2 = gtk_label_new( " p r o g r a żółźm " );
   
    gtk_container_add( GTK_CONTAINER( kontener ), napis2 );
    linia = gtk_hseparator_new();
    gtk_box_pack_start( GTK_BOX( kontener ), linia, FALSE, TRUE, 17 );
   
    napis = gtk_label_new( NULL );
   
    gtk_label_set_markup( GTK_LABEL( napis ), zm );
   
    gtk_container_add( GTK_CONTAINER( kontener ), napis ); // dodanie etykiety do kontenera cbox
   
    ptxt = gtk_entry_new();
    gtk_container_add( GTK_CONTAINER( kontener ), ptxt ); // dodanie pole txt do vboxa
   
    gtk_box_pack_start( GTK_BOX( kontener ), przycisk, FALSE, FALSE, 0 );
   
    g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), NULL );
   
    g_signal_connect( G_OBJECT( okno ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
    gtk_widget_show_all( okno );
    gtk_main();
    return 0;
}
P-58567
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-06-18 15:50:57
Ref
P-58632
Badman
» 2012-06-19 13:59:36
Przyjżysz się http://developer.gnome.org/gtk3/stable/GtkButton.html#GtkButton-clicked

Wynika, że funkcja obsługująca sygnał clicked obsługuje dwa parametry i to w dodatku pierwszy to zawsze wskaźnik kontrolki przycisku, który wysłał ten sygnał, a drugi to dowolny przesłany przez Ciebie.
U Ciebie skojarzony sygnał jest w ten sposób:
g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), NULL );


a funkcja obsługująca, która nie jest zgodna z obsługą sygnału u Ciebie wygląda tak:
void dalej( GtkWidget * okno, GtkWidget * obraz, GtkWidget * kontener2, GtkWidget * okno2 )
zatem w zmiennej okno masz adres przycisku, a obraz ma wrtość NULL przesłany w kojarzeniu sygnału z przycisku. W zmiennych kontener2, okno2 masz śmieci.

Ponieważ g_signal_connect pozwala przesłać tylko jeden pramatr masz 2 możliwości:
  • Wykorzystanie zmiennych globalnych, co jest nie wskazane
  • Przesłanie struktury - wskazane i tak zawsze rób !

Reasumująć kojarzenie sygnału może wyglądać tak:
g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), ptxt );

funkcja obsłujaca sygnał tak:
C/C++
void dalej( GtkButton * przycisk, gpointer dane )
{
    GtkWidget * kontener2;
    GtkWidget * okno2;
    GtkWidget * etykieta;
    gchar * tekst;
   
   
    okno2 = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    kontener2 = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno2 ), kontener2 );
   
    //Pobranie zawartosci kontrolki z konwersja na GTK_ENTRY
    tekst = gtk_entry_get_text( GTK_ENTRY( dane ) );
   
    etykieta = gtk_label_new( tekst );
    gtk_container_add( GTK_CONTAINER( kontener2 ), etykieta );
   
    gtk_widget_show_all( okno2 );
   
    // Wyczyszczenie zawartosci
    gtk_entry_set_text( GTK_ENTRY( dane ), "" );
}
P-58690
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-06-19 21:53:45
Dzięki za odpowiedź.
Program powinien teraz wyglądać tak?

C/C++
#include <gtk/gtk.h>

void dalej( GtkButton * przycisk, gpointer dane )
{
    GtkWidget * kontener2;
    GtkWidget * okno2;
    GtkWidget * etykieta;
    gchar * tekst;
   
   
    okno2 = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    kontener2 = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno2 ), kontener2 );
   
    //Pobranie zawartosci kontrolki z konwersja na GTK_ENTRY
    tekst = gtk_entry_get_text( GTK_ENTRY( dane ) ); // tu błąd
   
    etykieta = gtk_label_new( tekst );
    gtk_container_add( GTK_CONTAINER( kontener2 ), etykieta );
   
    gtk_widget_show_all( okno2 );
   
    // Wyczyszczenie zawartosci
    gtk_entry_set_text( GTK_ENTRY( dane ), "" );
}

int main( int argc, char * argv[] )
{
    GtkWidget * okno;
    GtkWidget * ptxt;
    GtkWidget * kontv;
    GtkWidget * przycisk;
   
    gtk_init( & argc, & argv );
    okno = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_position( GTK_WINDOW( okno ), GTK_WIN_POS_CENTER );
    gtk_window_set_title( GTK_WINDOW( okno ), "Kużółrs GTK+" );
    gtk_window_set_default_size( GTK_WINDOW( okno ), 150, 150 );
    //gtk_window_set_resizable( GTK_WINDOW( okno ), FALSE );
    ////
    kontv = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno ), kontv );
   
    ptxt = gtk_entry_new();
    gtk_container_add( GTK_CONTAINER( kontv ), ptxt );
   
    przycisk = gtk_button_new_with_label( "dalej" );
    gtk_container_add( GTK_CONTAINER( kontv ), przycisk );
   
    g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), ptxt );
    ////
    g_signal_connect( G_OBJECT( okno ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
    gtk_widget_show_all( okno );
    gtk_main();
    return 0;
}

error: invalid conversion from 'const gchar*' to 'gchar*'

Gdy usuwam
tekst = gtk_entry_get_text( GTK_ENTRY( dane ) );
program się kompiluje, ale za każdym kliknięciem na przycisk robi się nowe okno. Tak miało być czy ja nie ogarniam(chyba tak) ?
Jeżeli nie używać zmiennych globalnych to zrobić takie coś.
C/C++
struct st
{
    GtkWidget * kontener2;
    GtkWidget * okno2;
    GtkWidget * etykieta;
    gchar * tekst;
};

I zainicjować w funkcji main?
P-58730
Badman
» 2012-06-20 11:55:31
Faktycznie
const gchar * gtk_entry_get_text( GtkEntry * entry );
. Mój profesor zawsze powtarzał "programuj tak, aby nie bło warning'ów", stosuje to przy programowanie mikrokontrolerów AVR w C, jednak na PC już mi się nie chce :)
Akurat mój kompilator pozwala "delikatnie" odbiegać co do prawidłowości typów i tylko dostałem ostrzeżenie:
[Warning] assignment discards qualifiers from pointer target type
zachowawczo to zignorowałem :(
Zmienną tekst zadeklaruj jako const gchar *tekst;

Tak pojawia się okno z tekstem, który został wpisany w kontrolce GtkEntry, a w Twoim przypadku ptxt. Następnie tekst w GtkEntry zostaje wymazany.

Co do struktury i jej przekazywania to zależy od koncepcji programu. Wydawało mi się, że zmienne:
C/C++
GtkWidget * kontener2;
GtkWidget * okno2;
GtkWidget * etykieta;
gchar * tekst;

potrzebne są na użytek funkcji dalej, dlatego zostały zadeklarowane jako jej zmienne lokalne. Wydawało mi się, że chcesz w nowym oknie wyświetlić tylko wpisany tekst.
Gdybyś chciał, żeby wpisany tekst pojawił się także w głównym oknie wtedy musiałbyś wykorzystać strukture:

C/C++
#include<gtk/gtk.h>

struct _wieledanych {
    GtkWidget * etykieta;
    GtkWidget * label;
};

void dalej( GtkButton * przycisk, gpointer * dane )
{
    GtkWidget * kontener2;
    GtkWidget * okno2;
    GtkWidget * etykieta;
    const gchar * tekst;
    struct _wieledanych * noweDane;
   
    noweDane =( struct _wieledanych * ) dane;
   
    okno2 = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    kontener2 = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno2 ), kontener2 );
   
    //Pobranie zawartosci kontrolki z konwersja na GTK_ENTRY
    tekst = gtk_entry_get_text( GTK_ENTRY( noweDane->etykieta ) );
   
    etykieta = gtk_label_new( tekst );
    gtk_container_add( GTK_CONTAINER( kontener2 ), etykieta );
   
    gtk_widget_show_all( okno2 );
   
    // Ustawienie tekstu w głównym oknie
    gtk_label_set_text( GTK_LABEL( noweDane->label ), tekst );
   
    // Wyczyszczenie zawartosci
    gtk_entry_set_text( GTK_ENTRY( noweDane->etykieta ), "" );
}


int main( int argc, char * argv[] )
{
    GtkWidget * okno;
    GtkWidget * ptxt;
    GtkWidget * napis;
    GtkWidget * kontener;
    GtkWidget * linia;
    GtkWidget * napis2;
    GtkWidget * przycisk;
    struct _wieledanych wieleDanych;
   
    gtk_init( & argc, & argv );
    okno = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_title( GTK_WINDOW( okno ), "Kurs GTK+" );
    gtk_window_set_position( GTK_WINDOW( okno ), GTK_WIN_POS_CENTER );
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 150 );
   
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 200 );
   
    przycisk = gtk_button_new_with_label( "dalej" );
    gtk_widget_set_size_request( przycisk, 10, 20 );
   
   
    kontener = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno ), kontener );
   
    linia = gtk_hseparator_new();
   
    char * zm = "<tt><u>Wpisz</u> swoje</tt><span bgcolor='#00FF00'> imie</span>"; // podanie i sformatowanie tekstu
    gtk_box_pack_start( GTK_BOX( kontener ), linia, FALSE, TRUE, 17 );
   
    napis2 = gtk_label_new( " p r o g r a żółźm " );
   
    gtk_container_add( GTK_CONTAINER( kontener ), napis2 );
    linia = gtk_hseparator_new();
    gtk_box_pack_start( GTK_BOX( kontener ), linia, FALSE, TRUE, 17 );
   
    napis = gtk_label_new( NULL );
   
    gtk_label_set_markup( GTK_LABEL( napis ), zm );
   
    gtk_container_add( GTK_CONTAINER( kontener ), napis ); // dodanie etykiety do kontenera cbox
   
    ptxt = gtk_entry_new();
    gtk_container_add( GTK_CONTAINER( kontener ), ptxt ); // dodanie pole txt do vboxa
   
    gtk_box_pack_start( GTK_BOX( kontener ), przycisk, FALSE, FALSE, 0 );
   
    wieleDanych.etykieta = ptxt;
    wieleDanych.label = napis2;
    g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), & wieleDanych );
   
    g_signal_connect( G_OBJECT( okno ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
    gtk_widget_show_all( okno );
    gtk_main();
    return 0;
}
P-58740
czosnek17
Temat założony przez niniejszego użytkownika
» 2012-06-22 20:28:22
Modyfikuję program, żeby wyświetlił w starym oknie zdjęcie samochodu, którego nazwę wpiszę, ale coś nie działa. Gtk jednak nie jest takie proste jak mi się wydawało... Obrazki się nie pojawiają. Co znowu źle?

C/C++
#include<gtk/gtk.h>
#include<string>

using namespace std;

struct _wieledanych {
    GtkWidget * etykieta;
    GtkWidget * label;
    GtkWidget * maluch;
    GtkWidget * lamb;
    GtkWidget * okno;
   
};

void dalej( GtkButton * przycisk, gpointer * dane )
{
    string lamborg = "lamborghini";
    string malucht = "maluch";
   
   
    GtkWidget * kontener2;
    GtkWidget * okno;
    GtkWidget * etykieta;
    GtkWidget * lamb;
    GtkWidget * maluch;
    const gchar * tekst;
    string txt;
    struct _wieledanych * noweDane;
   
    noweDane =( struct _wieledanych * ) dane;
   
    tekst = gtk_entry_get_text( GTK_ENTRY( noweDane->etykieta ) );
    txt = tekst;
   
    if( txt == "lamborghini" || txt == "maluch" )
    {
       
        if( txt == "lamborghini" )
        {
            lamb = gtk_image_new_from_file( "lamb.gif" ); //// jeżeli używam tego nie ma warningów...
            gtk_container_add( GTK_CONTAINER( okno ), lamb ); //
        }
       
        if( txt == "maluch" )
        {
            maluch = gtk_image_new_from_file( "obraz.gif" ); ////
            gtk_container_add( GTK_CONTAINER( okno ), maluch ); //...jeżeli nie używam, tu i wyżej są
        }
       
    }
    else
    {
       
        etykieta = gtk_label_new( tekst );
        gtk_container_add( GTK_CONTAINER( kontener2 ), etykieta );
       
       
    }
   
}


int main( int argc, char * argv[] )
{
    GtkWidget * okno;
    GtkWidget * ptxt;
    GtkWidget * napis;
    GtkWidget * kontener;
    GtkWidget * linia;
    GtkWidget * napis2;
    GtkWidget * przycisk;
    GtkWidget * lam;
    GtkWidget * mal;
    struct _wieledanych wieleDanych;
   
   
    gtk_init( & argc, & argv );
    okno = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    gtk_window_set_title( GTK_WINDOW( okno ), "Kurs GTK+" );
    gtk_window_set_position( GTK_WINDOW( okno ), GTK_WIN_POS_CENTER );
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 150 );
   
    gtk_window_set_default_size( GTK_WINDOW( okno ), 300, 200 );
   
    przycisk = gtk_button_new_with_label( "dalej" );
    gtk_widget_set_size_request( przycisk, 10, 20 );
   
   
    kontener = gtk_vbox_new( FALSE, 1 );
    gtk_container_add( GTK_CONTAINER( okno ), kontener );
   
    napis2 = gtk_label_new( " ~samochód~ " );
   
    lam = gtk_image_new_from_file( "lamb.gif" ); // po użyciu tego i wieleDanych.lamb = lam; (poniżej) jest warning
    mal = gtk_image_new_from_file( "obraz.gif" );
   
    gtk_container_add( GTK_CONTAINER( kontener ), napis2 );
    linia = gtk_hseparator_new();
    gtk_box_pack_start( GTK_BOX( kontener ), linia, FALSE, TRUE, 17 );
   
    napis = gtk_label_new( NULL );
    gtk_container_add( GTK_CONTAINER( kontener ), napis );
   
    ptxt = gtk_entry_new();
    gtk_container_add( GTK_CONTAINER( kontener ), ptxt );
   
    gtk_box_pack_start( GTK_BOX( kontener ), przycisk, FALSE, FALSE, 0 );
   
    wieleDanych.etykieta = ptxt;
    wieleDanych.label = napis2;
    wieleDanych.lamb = lam;
    wieleDanych.maluch = mal;
   
    g_signal_connect( przycisk, "clicked", G_CALLBACK( dalej ), & wieleDanych );
   
    g_signal_connect( G_OBJECT( okno ), "destroy", G_CALLBACK( gtk_main_quit ), NULL );
    gtk_widget_show_all( okno );
    gtk_main();
    return 0;
}

warning: 'lamb' may be used uninitialized in this function|
.
warning: 'maluch' may be used uninitialized in this function|

Da się w gtk wprowadzić tekst enterem?
P-58933
1 « 2 » 3 4 5
Poprzednia strona Strona 2 z 5 Następna strona