Im very new to gui programming in linux and Im stumbling at the 1st hurdle, Im using glade to design a form (i come from windows background) it looks completly different in Glade than it does when I run the compiled program.
heres a screen grab of them
see link as they wont let me post images
heres the c++
#include <gtk/gtk.h>
void close_app(GtkWidget* widget,gpointer user_data) {
gtk_main_quit();
}
int main (int argc, char **argv) {
GtkBuilder *gtkBuilder;
GtkWidget *mainwin;
gtk_set_locale();
gtk_init (&argc, &argv);
gtkBuilder= gtk_builder_new();
gtk_builder_add_from_file(gtkBuilder,"test2.glade",NULL);
gtk_builder_connect_signals ( gtkBuilder, NULL );
mainwin= GTK_WIDGET(gtk_builder_get_object(gtkBuilder,"window1"));
g_object_unref ( G_OBJECT(gtkBuilder) );
gtk_widget_show_all ( mainwin );
gtk_main ();
return 0;
}
im on debian squeeze and im using libgtk2.0-dev version 2.20 libgnome2.24 <- I dont even know if this mught be the problem?
any ideas?
Thanks
You have nothing in the empty spaces in your HBox and VBox. If there are no other widgets taking up the space, then your button will expand to fill all available space. Put some other widgets in your window if you don't want the button to fill it. Sizing and placement work differently in GTK than they do in other toolkits, the idea is to build a user interface that still looks good when the user resizes the window or when the UI strings change length because the user is using your application in another language.
See the relevant section of the GTK tutorial or this other tutorial.
Related
Having trouble adding background image on the widget, even though I referenced the recent codes online.
This is my current code for main.cpp:
#include <QApplication>
#include <QWidget>
int main (int argc, char **argv){
QApplication app (argc,argv);
QWidget *w=new QWidget();
w->setStyleSheet("background-image: url(:/cover.jpg);");
w->setWindowTitle("Test");
w->show();
return app.exec();
}
After executing the code, how come the widget remains blank? Thanks in advance!
QtCreator is an IDE designed by Qt. It's just an interface.
I checked your implementation and I don't see anything wrong. It also work well on my pc. Can you check your image url or try with another image ?
Btw, if you're on linux, try removing : character after url ;
w->setStyleSheet("background-image: url(/cover.jpg);");
EDİT:
If jpg is in the same directory with your application, it should be ;
w->setStyleSheet("background-image: url(./cover.jpg);");
You can give a full path to avoid this kind of errors.
"Is it possible to add background image on QWidget without using QtCreator?"
Yes, of course it is.
QtCreator is just an IDE. You don't need to use it at all to write code using the Qt library.
Just as you can use it to write code that does not use Qt at all.
We have an application (QCoreApplication) that takes some images as input, does something to them, and exports them again. We now need to add some text to the images, and tried to do this with the QPainter class. It all worked well when using it in one of our other apps (using QApplication), but not in our main QCoreApplication app.
Here is the code:
void drawTextOnImage(QImage* image, const QString& text, const QFont& font)
{
QPainter p;
if (!p.begin(image)) return;
p.setFont(font);
p.drawText(image->rect(), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, text);
p.end();
}
The application crashes on the drawText line.
Any ideas?
It is a very simple text, so suggestions without using Qt will also be appreaciated.
When using classes from "Qt Gui" like QPainter, you are supposed to use a QGuiApplication, not a QCoreApplication.
You might get lucky and be able to make some GUI stuff works while using only a QCoreApplication. But as you have discovered, it makes your application very brittle. Some classes like QPixmap will print an error message, but others will just crash.
The same is applicable with "Qt Widget": if you use a widget related class, you must use a QApplication.
Note that since QApplication inherits QGuiApplication, if you have a QApplication you can use "Qt Gui".
In case you need to run a non-GUI application on something without a windowing system, you need, aside from creating an instance of QGuiApplication, to also choose an appropriate Qt platform.
For me, offscreen platform worked fine. I was generating images with textual elements and saving them to files on a headless Raspberry Pi. My code then was like the example below. Note that setenv is a POSIX function and may need a replacement on Windows, though I'm not sure whether windowless Windows is a thing at all.
#include <stdlib.h>
#include <QImage>
#include <QPainter>
#include <QGuiApplication>
int main(int argc, char** argv)
{
setenv("QT_QPA_PLATFORM","offscreen",1);
QGuiApplication app(argc,argv);
QImage img(128,128, QImage::Format_RGB888);
img.fill(Qt::white);
QPainter p(&img);
p.drawText(QPoint(0,64), "Works!");
img.save("/tmp/test.png");
}
On a machine running Windows, the MenuItems are too small for my use case.
Therefore, my question is, "how I may increase the font size of the text "Save", "Load" and "Exit?" "
If not, then how can I increase the padding between the MenuItems?
(without adding more of those line separators as seen between "Load" and "Exit")
Additionally, how may I remove the intermediate variable SubMenu1, if possible?
Cropped Screenshot
Below is a complete source to reproduce:
#include <gtk/gtk.h>
int main (int argc, char *argv[]) {
gtk_init (&argc, &argv);
GtkWidget* Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* MenuBar = gtk_menu_bar_new();
GtkWidget* MenuItem_File = gtk_menu_item_new_with_mnemonic("_File");
GtkWidget* SubMenu1 = gtk_menu_new();
GtkWidget* Item_Save = gtk_menu_item_new_with_mnemonic("_Save");
GtkWidget* Item_Load = gtk_menu_item_new_with_mnemonic("_Load");
GtkWidget* Item_Exit = gtk_menu_item_new_with_mnemonic("_Exit");
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Save);
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Load);
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), gtk_separator_menu_item_new());
gtk_menu_shell_append(GTK_MENU_SHELL(SubMenu1), Item_Exit);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(MenuItem_File), SubMenu1);
gtk_menu_shell_append(GTK_MENU_SHELL(MenuBar), MenuItem_File);
GtkWidget* VerticalBox;
VerticalBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(VerticalBox), MenuBar, false, false, 0);
gtk_container_add(GTK_CONTAINER(Window), VerticalBox);
gtk_widget_show_all(MenuBar);
gtk_widget_show(VerticalBox);
gtk_window_set_default_size(GTK_WINDOW(Window), 950, 600);
gtk_window_set_position(GTK_WINDOW(Window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(Window), "My Title");
gtk_widget_show(Window);
gtk_main();
return 0;
}
Gtk3's font size control (and other style properties) are delegated to the CSS files. It is generally discouraged to do this in your program (though this is certainly possible - have a look at Gtk3's CSS_provider functions). But normally you would like your program to look 'compatible' with other programs, I suspect.
The reason is that the aspect of your program should be controllable from the outside - be it for reasons of personal taste, or for accessibility. So, if you consider the font style for the menus etc, too small, you can:
Choose another 'theme' or style, eg. on the Gnome-Look site
Look at the Window manager's preferences for an 'Appearance' setting (as it is called in XFCE. There are similar tools in Gnome, KDE, etc.)
Modify the CSS files of the theme you are currently using
Many other visual aspects are controlled from the CSS files: Separation between elements (eg. menuitems), rounding of corners, visual effects, etc etc... but, thanks to the CSS system, you can normally just 'tweak' the items you like.
EDIT: If you want to run the executable on another machine, you'd probably need a window manager to run it under, which makes the above still valid.
There is still another solution (which I mentioned above, first paragraph), which is to change the CSS temporarily using the CSS provider set of Gtk functions. If you really want to code program rigidly, you can use the modify_font method of GtkWidget.
I've tried in 2 forums, but I had no luck so far.
So, I am using Qt IDE in order to build my application so as to participate to the Ubuntu Showdown contest. In my application, I've done the following:
void show_app(MainWindow *data)
{
//this works fine:
app_indicator_set_status(appindicator, APP_INDICATOR_STATUS_PASSIVE);
//this crashes the application:
data->show();
}
void MainWindow::make_indicator()
{
if(appindicator){
//appindicator has already been created
return;
}
appindicator = app_indicator_new("Format Junkie Indicator", "formatjunkie", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
GtkWidget* showapp_option;
GtkWidget* indicatormenu = gtk_menu_new();
GtkWidget* item = gtk_menu_item_new_with_label("Format Junkie main menu");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), indicatormenu);
showapp_option = gtk_menu_item_new_with_label("Show App!");
g_signal_connect(showapp_option, "activate", G_CALLBACK(show_app), this);
gtk_menu_shell_append(GTK_MENU_SHELL(indicatormenu), showapp_option);
gtk_widget_show_all(indicatormenu);
app_indicator_set_status(appindicator, APP_INDICATOR_STATUS_ACTIVE);
app_indicator_set_attention_icon(appindicator, "dialog-warning");
app_indicator_set_menu(appindicator, GTK_MENU (indicatormenu));
}
So, basically I am trying to make a simple indicator entry, which, on click, it will hide the indicator and display the application. The indicator can be successfully hidden using the PASSIVE thingy over there, but, during the call data->show();, the application crashes.
Any help on what I am doing wrong would be appreciated! Also, please help me to correct this problem I'm facing (alternatively, I will migrate to the old and good tray icon (it works fine in Ubuntu 12.04, anyway) which I can handle very easily and efficiently)
The callback for the activate signal needs to have the following type:
void callback(GtkMenuItem *, gpointer)
So show_app should be defined like this
void show_app(GtkMenuItem *showapp_option, MainWindow *data)
That should solve your problem.
Here is a sample from Allegro5 tutorial: (to see the original sample, follow the link, I've simplified it a bit for illustratory purposes.
#include <allegro5/allegro.h>
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
al_init()
display = al_create_display(640, 480);
event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_display_event_source(display));
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
while(1)
{
ALLEGRO_EVENT ev;
ALLEGRO_TIMEOUT timeout;
al_init_timeout(&timeout, 0.06);
bool get_event = al_wait_for_event_until(event_queue, &ev, &timeout);
//-->// if(get_event && ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
//-->// break;
//-->// }
al_clear_to_color(al_map_rgb(0,0,0));
al_flip_display();
}
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}
If I don't manually check for the ALLEGRO_EVENT_DISPLAY_CLOSE, then I can't close the window or terminate the program (without killing the process through task manager). I understand this. But in this case I don't understand how the minimize button works without me manually handling it. Can someone please explain?
Disclaimer: I don't know Allegro.
Minimizing a window at the most basic level only involves work from the process that deals with the windows (the Window Manager), not the process itself.
Terminating a program, usually requires files to be closed or memory to be freed or something else that only the process itself can do.
The biggest reason that you must handle it yourself via an event is that closing (destroying) a window invalidates the ALLEGRO_DISPLAY * pointer. The request to terminate the window comes from a different thread, so it would be unsafe to destroy it immediately. Allowing you to process it yourself on your own time is safe and easy, and fits in with the event model that Allegro 5 uses for all other things.
There are other ways to solve the problem, but they are no more simple than this method and don't really have any major advantages.
I don't know anything about allegro, but minimizing windows is generally handled by the window manager without the need of further intervention by your program. The main window is set to a "minimized"-state and your program continues running in the background without a visible window.
You can check if your app is being minized by intercepting specific window-messages (those being WM_ACTIVATEAPP, WM_ACTIVATE or WM_SIZE). Maybe allegro provides something like that, too.
In contrast closing the window does need to be done by your program. Clicking on the X simply sends a message to the window (WM_CLOSE), that the user has clicked it, and you have to respond accordingly (save states, quit the program, or you could prevent it).
At least that's how the normal winapi works, and allegro seems to work the same way.