我希望我能很好地描述这个问题。我几天前跑了pacman Syu
,我正在努力的GTK应用程序停止正常工作。之后我再次运行它,但问题仍然存在。
基本上,程序没有正确响应。作为一个例子,我有一个按钮,当按下时,应该打印" aqui"到控制台,然后向上移动画布(如,向上导航)。但是,画布未更新,并且不打印输出。只有当我关闭申请时," aqui"按下按钮时打印的次数很多。
应用程序似乎在打开另一个窗口时响应。如果我单击打开不同窗口的按钮,累积的更改将生效(多次" aqui"打印,并且画布向上移动的次数与我单击的次数相同)。当我点击应该关闭新窗口的按钮时,按钮消失,但窗口仍然存在。例如:
这是向上按钮的代码:
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;
}
旋转按钮的代码,用于打开图片中显示的较小窗口:
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;
}
点击rotateW
时调用的okButton
方法:
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;
}
和main
方法:
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;
}
如果这还不够,则完整代码位于github。我提前道歉,代码很乱。
修改
将std::endl
添加到std::cout
的末尾解决了实时未打印字符串的问题。现在,当我按下按钮时,它们正在打印,但按钮的其余功能(与影响界面有关)仍然无法更新,直到另一个窗口打开。
编辑2
I made a gif showing how it's behaving right now.
我尝试将gtk从3.20.6降级到3.16.1,但这并没有奏效。我还尝试降级每个包(通过编辑/etc/pacman.conf
然后运行pacman -Syyuu
)到2016年3月30日,也没有工作。
我还尝试删除gtk main()
的其他实例但没有成功。
刚尝试添加此代码:
if(gtk_events_pending())
gtk_main_iteration();
哪一个力一次运行主循环。这也没有解决问题。
答案 0 :(得分:1)
您可能希望强制GTK刷新其待处理操作。
我用python这样做:
while gtk.events_pending(): # this forces GTK to refresh the screen
gtk.main_iteration()
由于你没有提到你正在使用的语言,你必须找到如何重现这个,但它可能只是
while gtk.events_pending(): # this forces GTK to refresh the screen
gtk.main_iteration();
答案 1 :(得分:1)
你的问题是你曾两次打电话给gtk_main
。在你的主要(这是好的)和你的rotateWindowWindow
功能(这是错误的)。这样做会创建一个新的主循环,在您退出之前,您将被卡住。
删除额外的通话应足以解决您的问题。