What are the rules for painting to the screen?
My end goal is to put the TCanvas into a class and paint from there, but for now I think that maybe looking at a less complicated example might help. Below is some code that compiles and paints to the screen, on my computer.
# include <TApplication.h>
# include <TCanvas.h>
# include <TH1D.h>
# include <thread>
# include <chrono>
//TCanvas canvas ("fCanvas", "fCanvas", 600, 400);
int main ( int argc, char* argv[] )
{
TApplication app ("app",&argc,argv);
TCanvas canvas ("fCanvas", "fCanvas", 600, 400);
//TCanvas* canvas = new TCanvas("fCanvas", "fCanvas", 600, 400);
TH1D h ("h","h",10,0,10);
h.Fill(1);
h.Fill(2);
h.Fill(2);
h.Fill(2);
h.Fill(3);
h.Fill(3);
h.Draw();
canvas.Update();
canvas.Draw();
std::this_thread::sleep_for( std::chrono::seconds(3) );
return 0;
}
You may notice some commented-out lines. If I use either of those definitions of canvas, using the appropriate member access operators on the later-called Update and Draw methods, the application crashes after printing a blank TCanvas-window to the screen. It also crashes if I change app and h to pointers.
If I try to instantiate a class using any sort of ROOT object at all, it crashes the application.
Right now, I'm compiling with MSVC++'s cl.exe and linking with link.exe. I'm working on a 64-bit Windows 7 Enterprise N. I'm trying to port an application that I built in Unix, for which a simple new TApplication("name",0,0); at the start of main made everything work.
So, to reiterate: how can I get my histograms onto the screen in this OS, and maybe others? I doubt that I'll be able to understand the "why", but it might be nice to write something about that for others reading this who can. Otherwise, just a step-by-step description of how to use these objects to paint would be wonderful.
Many thanks for any help on this; I'll gladly provide more information / examples if that should prove useful.
Update: it works in my particular case if I compile with something like
cl -nologo -DWIN32 -W3 -D_WINDOWS -Z7 -MDd -GR -EHsc main.cxx -I %ROOTSYS%\include -FIw32pragma.h /link -debug -LIBPATH:%ROOTSYS%\lib libCore.lib libRIO.lib libHist.lib libGpad.lib
Not sure why.
See https://root.cern.ch/phpBB3/viewtopic.php?f=3&t=3402&p=85329&hilit=Vector+stl+of+TH1F*+Objects#p85329 .
I usually use TApplications like below to have TCanvases really appear as window on the screen.
#include "TApplication.h"
// other stuff
int main(int argc, char** argv) {
TApplication theApp("App",&argc, argv);
// your code
// here you can Draw() things
theApp.Run();
return 0;
}
The program then just stops at Run() and I end the process with ^C.
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 been stuck on this for a little while now, I'm trying to set the drag mode of my QGraphicsView to ScrollHandDrag so that I can build a panning feature on my application.
However whenever I try to set the drag mode Qt always complains that DragMode is an undeclared identifier.
I'm also aiming to build a crop functionality (I assume I'd be using rubber band dragging for that?), I'm just wondering why I can't set the drag mode on the View
void MainWindow::on_btnCrop_clicked()
{
cropping = true;
QApplication::setOverrideCursor(Qt::CrossCursor);
// Stuck with this...
ui->imageView->setDragMode(ScrollHandDrag);
}
^ I have tried multiple other workarounds but I've not yet found any solution, any suggestions would be greatly appreciated.
This is not QGraphicsView specific an issue, but generic C++. Your problem is located at this line:
ui->imageView->setDragMode(ScrollHandDrag);
The problem is that you assume that you have visibility to the ScrollHandDrag value, whereas it appears inside the QGraphicsView scope. Therefore, since you are trying to access that value in your MainWindow, you will need add the scope explicitly as follows:
ui->imageView->setDragMode(QGraphicsView::ScrollHandDrag);
Note that how even the documentation specifies the scope for this constant:
QGraphicsView::ScrollHandDrag 1 The cursor changes into a pointing hand, and dragging the mouse around will scroll the scrolbars. This mode works both in interactive and non-interactive mode.
Here is my minimal building code:
#include <QGraphicsView>
int main()
{
QGraphicsView graphicsView;
graphicsView.setDragMode(QGraphicsView::ScrollHandDrag);
return 0;
}
main.pro
TEMPLATE = app
TARGET = main
QT += widgets
SOURCES += main.cpp
Build and Run
qmake && make
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.