2016-05-24 14 views
1

Ich hoffe, ich kann dieses Problem gut beschreiben. Ich lief pacman Syu vor ein paar Tagen und die GTK-Anwendung, an der ich arbeite, hörte auf, richtig zu funktionieren. Ich habe es wieder ausgeführt, aber das Problem besteht weiter.Gtk + nicht die Widgets korrekt aktualisieren

Grundsätzlich reagiert das Programm nicht richtig. Als Beispiel habe ich eine Taste, die, wenn sie gedrückt wird, "aqui" auf die Konsole druckt und dann die Leinwand nach oben bewegt (wie in, hoch). Die Zeichenfläche wird jedoch nicht aktualisiert, und die Ausgabe wird nicht gedruckt. Nur wenn ich die Anwendung schließe, wird "aqui" so oft gedruckt, wie ich den Knopf gedrückt habe.

Die Anwendung scheint zu reagieren, wenn ein anderes Fenster geöffnet wird. Wenn ich auf eine Schaltfläche klicke, die ein anderes Fenster öffnet, werden die akkumulierten Änderungen wirksam (mehrere "aqui" werden gedruckt, und die Leinwand wird so oft nach oben verschoben, wie ich geklickt habe). Wenn ich auf die Schaltfläche klicke, die das neue Fenster schließen soll, verschwindet die Schaltfläche, aber das Fenster ist immer noch da. Beispiel:

The new window, asking for an input

After clicking OK

Dies ist der Code für die Aufwärtstaste:

static gboolean moveUp(GtkWidget *widget, GdkEventButton *event, 
    gpointer user_data) 
{ 
    windowData->moveY(STEP); 
    gtk_widget_queue_draw((GtkWidget*) user_data); 
    std::cout << "aqui"; 
    return TRUE; 
} 

den Code für die Schaltfläche Drehen, dass die kleineren Fenster in den Bildern zu sehen öffnet:

static gboolean rotateWindowWindow(GtkWidget *widget, GdkEventButton *event, 
    gpointer user_data) { 
    GtkBuilder *builder; 
    GError *error = NULL; 

    builder = gtk_builder_new(); 

    if (!gtk_builder_add_from_file(builder, "rotateWindow.glade", &error)) { 
    g_warning("%s", error->message); 
    g_free(error); 
    } 

    GtkWidget *rotateWindowWindow; 

    rotateWindowWindow = GTK_WIDGET(gtk_builder_get_object(builder, "rotateWindowWindow")); 
    rotationAngle = (GtkEntry*) GTK_WIDGET(gtk_builder_get_object(builder, "rotationAngle")); 
    GtkWidget* okButton = GTK_WIDGET(gtk_builder_get_object(builder, "okButton")); 

    g_signal_connect(G_OBJECT(okButton), "clicked", G_CALLBACK(rotateW), rotateWindowWindow); 

    gtk_builder_connect_signals(builder, NULL); 
    g_object_unref(G_OBJECT(builder)); 
    gtk_widget_show_all(rotateWindowWindow); 
    gtk_main(); 

    return TRUE; 
} 

die rotateW Methode, die aufgerufen wird, wenn die okButton klicken:

static gboolean rotateW(GtkWidget *widget, GdkEventButton *event, 
    gpointer user_data) 
{ 
    double angle = atof(gtk_entry_get_text(GTK_ENTRY(rotationAngle))); 
    windowData->rotate(angle); 

    displayFile->rotateAll(windowData->getAngle(), windowData->getCenter()); 

    gtk_widget_destroy((GtkWidget*) user_data); 
    return TRUE; 
} 

und die main Methode:

int main(int argc, char **argv) 
{ 
    GtkWidget  *viewport, *buttonUp, 
    *buttonDown, *buttonLeft, *buttonRight, *buttonZoomIn, 
    *buttonZoomOut, *newLine, *listWindow, *mainBox, *buttonClose, 
    *newPolygon, *newPoint, *translateButton, *scaleButton, 
    *rotateButton, *rotateWindowButton; 
    GtkDrawingArea *drawingArea; 
    GError   *error = NULL; 

    origin.x = 0; 
    origin.y = 0; 

    viewportData = new Viewport(300.0, 350.0); 
    windowData = new Window(300.0, 350.0); 
    sh = new SutherlandHodgeman(windowData); 
    cs = new CohenSutherland(windowData); 
    nc = new NoClipping(windowData); 
    clipper = nc; 

    displayFile = new DisplayFile(); 

    Polygon* l = new Polygon("line"); 
    l->addPoint(0, 0); 
    l->addPoint(100, 0); 
    displayFile->add(l); 

    //l = new Polygon("line2"); 
    //l->addPoint(5, 5); 
    //l->addPoint(500, 15); 
    //displayFile->add(l); 

    /* Init GTK+ */ 

    gtk_init(&argc, &argv); 

    /* Create new GtkBuilder object */ 
    mainBuilder = gtk_builder_new(); 

    /* Load UI from file. If error occurs, report it and quit application. 
    * Replace "tut.glade" with your saved project. */ 
    if(! gtk_builder_add_from_file(mainBuilder, "interface.glade", &error)) 
    { 
     g_warning("%s", error->message); 
     g_free(error); 
     return 1; 
    } 

    /* Get main window pointer from UI */ 
    mainWindow = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "mainWindow")); 
    viewport = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "viewport")); 
    drawingArea = GTK_DRAWING_AREA(gtk_builder_get_object(mainBuilder, "drawingArea")); 
    listWindow = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "listWindow")); 
    buttonClose = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "buttonClose")); 
    mainBox = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "mainBox")); 
    buttonUp = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "buttonUp")); 
    buttonLeft = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "buttonLeft")); 
    buttonRight = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "buttonRight")); 
    buttonDown = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "buttonDown")); 
    buttonZoomIn = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "zoomIn")); 
    buttonZoomOut = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "zoomOut")); 
    translateButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "translateButton")); 
    scaleButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "scaleButton")); 
    rotateButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "rotateButton")); 
    newPolygon = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "newPolygon")); 
    newLine = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "newLine")); 
    newPoint = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "newPoint")); 
    cohenButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "cohenButton")); 
    sutherlandButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "hodgemanButton")); 
    noClippingButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "noClipping")); 
    rotateWindowButton = GTK_WIDGET(gtk_builder_get_object(mainBuilder, "rotateWindow")); 

    g_signal_connect(mainWindow, "delete_event", G_CALLBACK(exit_app), NULL); 
    g_signal_connect(buttonClose, "clicked", G_CALLBACK(exit_app), NULL); 
    g_signal_connect(G_OBJECT(drawingArea), "draw", G_CALLBACK(on_draw_event), NULL); 
    g_signal_connect(G_OBJECT(buttonUp), "clicked", G_CALLBACK(moveUp), mainWindow); 
    g_signal_connect(G_OBJECT(buttonDown), "clicked", G_CALLBACK(moveDown), mainWindow); 
    g_signal_connect(G_OBJECT(buttonLeft), "clicked", G_CALLBACK(moveLeft), mainWindow); 
    g_signal_connect(G_OBJECT(buttonRight), "clicked", G_CALLBACK(moveRight), mainWindow); 
    g_signal_connect(G_OBJECT(buttonZoomIn), "clicked", G_CALLBACK(zoomIn), mainWindow); 
    g_signal_connect(G_OBJECT(buttonZoomOut), "clicked", G_CALLBACK(zoomOut), mainWindow); 
    g_signal_connect(G_OBJECT(translateButton), "clicked", G_CALLBACK(translateWindow), mainWindow); 
    g_signal_connect(G_OBJECT(rotateButton), "clicked", G_CALLBACK(rotateWindow), mainWindow); 
    g_signal_connect(G_OBJECT(scaleButton), "clicked", G_CALLBACK(scaleWindow), mainWindow); 
    g_signal_connect(G_OBJECT(newLine), "clicked", G_CALLBACK(newLineWindow), NULL); 
    g_signal_connect(G_OBJECT(newPolygon), "clicked", G_CALLBACK(newPolygonWindow), NULL); 
    g_signal_connect(G_OBJECT(newPoint), "clicked", G_CALLBACK(newPointWindow), NULL); 
    g_signal_connect(G_OBJECT(cohenButton), "clicked", G_CALLBACK(changeClipping), mainWindow); 
    g_signal_connect(G_OBJECT(sutherlandButton), "clicked", G_CALLBACK(changeClipping), mainWindow); 
    g_signal_connect(G_OBJECT(noClippingButton), "clicked", G_CALLBACK(changeClipping), mainWindow); 
    g_signal_connect(G_OBJECT(rotateWindowButton), "clicked", G_CALLBACK(rotateWindowWindow), mainWindow); 
    /* Connect signals */ 
    gtk_builder_connect_signals(mainBuilder, NULL); 

    /* Destroy builder, since we don't need it anymore */ 
    //g_object_unref(G_OBJECT(mainBuilder)); 

    /* Show window. All other widgets are automatically shown by GtkBuilder */ 
    gtk_widget_show_all(mainWindow); 

    /* Start main loop */ 
    gtk_main(); 

    return 0; 
} 

Ist dies nicht genug ist, ist der vollständige Code auf github. Ich entschuldige mich im Voraus, der Code ist ein Durcheinander.


EDIT

std::endl bis zum Ende der std::cout Hinzufügen löste das Problem der Strings nicht in Echtzeit gedruckt werden. Jetzt werden sie gedruckt, wenn ich den Knopf drücke, aber der Rest der Funktionalität des Knopfes, der mit dem Beeinflussen der Schnittstelle zu tun hat, wird immer noch nicht aktualisiert, bis ein anderes Fenster geöffnet wird.


EDIT 2

I made a gif showing how it's behaving right now.

Ich versuchte gtk von 3.20.6 bis 3.16.1 Herabstufung, die Arbeit nicht. Ich habe auch versucht, jedes Paket (durch Bearbeiten /etc/pacman.conf und dann pacman -Syyuu) bis 03/30/2016 herunterzurüsten, auch nicht funktioniert.

Ich habe auch versucht, andere Instanzen von gtk main() ohne Erfolg zu entfernen.

habe gerade versucht, diesen Code hinzu:

if(gtk_events_pending()) 
    gtk_main_iteration(); 

, die die Hauptschleife zwingen, ein einziges Mal ausgeführt wird. Das hat das Problem auch nicht gelöst.

+0

Haben Sie das Pacman-Protokoll überprüft? – oldtechaa

+0

@oldtechaa was suche ich auf den logs? Es gibt keine Fehler, zumindest explizit – Tuma

+0

Schauen Sie, was aktualisiert wurde. Ein zufälliges Problem auf einem Pacman-Update sieht wie ein Fehler in der Verpackung oder der Upstream-Software aus. Aber wir können nicht herausfinden, was das Paket ist, ohne die Protokolle zu betrachten. – oldtechaa

Antwort

0

Sie können GTK zwingen, seine ausstehenden Vorgänge zu aktualisieren.

Ich mache es in Python auf diese Weise:

while gtk.events_pending():  # this forces GTK to refresh the screen 
    gtk.main_iteration()   

Wie Sie erwähnen nicht, welche Sprache Sie verwenden, werden Sie herausfinden müssen, wie dies zu reproduzieren, aber es ist wahrscheinlich nur

while gtk.events_pending():  # this forces GTK to refresh the screen 
    gtk.main_iteration(); 
+0

Ich habe Ihre Antwort einfach auf der Grundlage der Tatsache herabgestimmt, dass aus dem bereitgestellten Code OP klar ist, dass er Python nicht verwendet, während Ihre Antwort ist und dass Sie nicht erklärt haben, warum diese Hilfe OP ist. (auch die Kommentare im Code erklären den Code überhaupt nicht) – B8vrede

+1

@ B8vrede: Ich habe gerade die Antwort bearbeitet. Das ist, wonach OP sucht. – Louis

+1

Ich denke, Sie haben Recht, die meisten Probleme, die hier in letzter Zeit gepostet werden, haben damit zu tun, dass GTK nicht in der Lage ist, seine Hauptdurchläufe zu machen. In diesem Fall ist dies eine gültige Antwort. :) – B8vrede

1

Ihr Problem ist, dass Sie zweimal anrufen gtk_main. In Ihrem Haupt (was in Ordnung ist) und in Ihrer rotateWindowWindow Funktion (was falsch ist). Dadurch wird eine neue Hauptschleife erstellt, in der Sie bis zum Beenden stecken bleiben.

Das Entfernen dieses zusätzlichen Anrufs sollte ausreichen, um das Problem zu beheben.

+0

hey thanks man, ich habe es versucht, aber es hat nicht funktioniert ... Ich habe ein paar Infos zum Beitrag hinzugefügt, mit ein paar Dingen, die ich ausprobiert habe – Tuma