How to get the XId of a Gtk::Window in Gtkmm4 - c++

I am using Gtkmm4, and lots of API has been removed. In Gtk3 one could use Gtk::Window::get_xid (inherited from Gdk::Window), but thats not possible anymore, because Gdk::Window has been renamed to Gdk::Surface, and Gtk::Window seems to not inherit from it anymore. But, one can always get the XId of a Gdk::Surface using GDK_SURFACE_XID(surface). How can i get the Gdk::Surface of a Gtk::Window, or alternatively, get the XId from a Gtk::Window directly ?
Note : i need only solutions using Gtkmm 4, not Gtkmm 3 !

The code that deals with the underlying surfaces got split off into a separate interface, Gtk::Native, which Gtk::Window then implements. Gtk::Native has a method get_surface() which should just work like Gtk::Window::get_window() did in GTK 3.

Related

How can I use gtk_window_set_transient_for ()?

I am using the library gtkmm. My code is almost perfect, I think because it compiles and I can execute it. But in the terminal when I clicked on open a file in my software that I made with gtkmm I can read this message :
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
So I looked for on this forum how can I solve it and I understood I have to use this method : gtk_window_set_transient_for().
Actually I have a Gtk::Window and a Gtk::FileChooserDialog. Can you put an example which use gtk_window_set_transient_for() ?
Thank you very much !
Gtk::FileChooserDialog and other GTK+ dialogues are derived from Gtk::Window. Gtk::Window has the method set_transient_for(Gtk::Window &parent); which if not set gives you the message you have seen.
To fix this set_transient_for(Gtk::Window &) needs to be used. Note that this takes a reference and not a pointer. So you would use it something like this.
{
Gtk::Window first_window;
...
Gtk::FileChooserDialog file_dialog("Title");
...
file_dialog.set_transient_for(first_window);
...
}
It is also possible to set the transient window for the dialog with the constructor. like so.
{
Gtk::Window first_window;
...
Gtk::FileChooserDialog file_dialog(first_window, "Title");
...
}
If first_window is a pointer the you would need to do something like so.
file_dialog.set_transient_for(*first_window);

QWidget transparency goes away when parent set

I want to have "flying" info above my interface (like informationnal text).
I have subclassed QWidget, set the FramelessWindowHint and TranslucentBackground flags.
So I create it with my interface's widget as ctor parameter, and style (style is in a ressource QSS file and set to qApp in main) does apply to my custom widget except for background (I can put a borderbut no background-color).
But when I make my custom widget it's own parent (I leave ctor parameters empty), then I can have my background changed.
I used this technique with the exact same flyingwidget class in another project and it worked just fine. QGLWidget may be in cause (creating widget before or after QGLWidget are created causes style to be applied or not).
here's the code where I create my widget.
Form_coupeHighlighterInfo *highlightCoupeInfo = new Form_coupeHighlighterInfo(this); //ctor parameter that changes
highlightCoupeInfo->setObjectName(QStringLiteral("highlightCoupeInfo"));
highlightCoupeInfo->attachToRight();
highlightCoupeInfo->setFixedWidth(400);
highlightCoupeInfo->setFixedHeight(400);
highlightCoupeInfo->setRelativePos(QPoint(-10, 0));
connect(this, SIGNAL(alignToInterface(QPointF&)), highlightCoupeInfo, SLOT(alignToInterface(QPointF&)));
I must add that background property doesn't work like the others but I don't get what the hell is going on with him, QSS looks like magic to me on a lot of points.
I use Qt 5.2.1 / msvc2012opengl / windows 7

Is it possible to set global QPainter default render hints?

When a QPainter is created, it has some default render hints. Some widgets override them when painting themselves. Is it possible to override these defaults and disable the per-widget overrides for the entire application?
I'd like to override the defaults as follows, and make all widget classes follow these:
painter->setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing, false);
painter->setRenderHints(QPainter::TextAntialiasing , true);
Is it possible?
UPDATE:
Short answer: not possible without changing Qt source code.
Unfortunately, Qt doesn't implement any public way of doing this.
There are two issues:
The default render hint - QPainter::TextAntialiasing is set in QPainter::begin(QPaintDevice*). This is exactly what you wanted according to your question, but
The widgets are free to override these defaults. And many of them do. There is no way to disable that, without inserting a shim paint engine (or similar) that would intercept these and ignore them.
The simplest way to change it is to modify the QPainter::setRenderHint and QPainter::setRenderHints to disable the overrides on certain widget types, and rebuild Qt. In any professional setting you'll be using your own build of Qt anyway, so that shouldn't be an issue.
There probably is a way of hooking it using Qt's private headers, most likely by offering a shim paint engine and swapping it out on the backing store, without modifying Qt itself, but it'll be messy and not worth it.
You can subclass QPainter with:
class MyQPainter: public QWidget
{
Q_OBJECT;
public:
MyQPainter(QWidget *parent = 0);
QPainter painter;
}
and:
MyQPainter::MyQPainter(QWidget *parent)
: QWidget(parent)
{
painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing, false);
painter.setRenderHints(QPainter::TextAntialiasing , true);
}
now, you can declare MyQPainter *pPainter = new MyQPainter();

Qt problem when working over classes GUI access

I got 2 classes:
- MainWindow (Was the default class)
- ExtraClass (That i created myself)
Inside the class MainWindow i've made a public function called "logger". This function looks like this:
// Takes in a QString and appends it to a QTextEdit.
void MainWindow::logger(QString Log_MSG)
{
ui->Logg->append(Log_MSG);
}
This logger functions works out as expected inside its own Class MainWindow but when i try to pass in a MSG into logger from the class ExtraClass, it suddenly doesn't work.
My approach to accessing logger from MainWindow to ExtraClass:
MainWindow Con;
Con.logger("The Message the will get appended to ui->logg");
So the question, what have i missed? I don't get any errors and the text "Log_MSG" that should be appended to the QTextEdit Log don't execute.
Sorry for the style, i just don't understand how to get it to look good.
EDIT:
I've already tried to access other functions from "MainWindow class"
and that works but when i try to pass a string this particuallry function "logger"
from another class nothing happens.
For an instance:
MainWindow MainWindow;
int ANumber = MainWindow.GiveMeAValue(); // This works
But when i'm doing this:
MainWindow MainWindow;
MainWindow.logger("Log MSG"); // This dosen't work
My guess is that the problem lies in the appendment of
a QString passed in into the main class that was automatically created by Qt (have stuff like ui->abc) from another class. But in my current
level of understandment of Qt i don't really know where to
troubleshoot beocuse i don't even get an error.
Your code to access the logger is wrong (it shouldn't even compile).
First, everytime you call the function where this code resides, you create a new local MainWindow object (Con). And then you try to call the method on the class and not on an object. If it is a static method (which I doubt, due to the use of ui), you would have to write MainWindow::logger(). If it is not a static method, then you need to call it on a specific MainWindow instance. But instead of creating a local MainWindow everytime, you should provide the correct application's MainWindow instance to your ExtraClass object.
If all this sounds alien to you, you should first look a bit deeper into fundamental C++ programming before delving into Qt.

Showing two windows in Qt4

My friend and I have each created parts of a GUI using Qt 4. They both work independently and I am trying to integrate his form with the my main window. As of now this is the code I am using to try and load his form:
//connect buttons and such
connect(exitbtn, SIGNAL(triggered()),this,SLOT(terminated()));
connect(add, SIGNAL(triggered()),this,SLOT(add_rec()));
void MainWindowImpl::add_rec()
{
//form quits as soon as it loads...?
DialogImpl dia;//name of his form
dia.show();
}
I have included his header file. The program compiles but when I hit the trigger his form loads up for maybe half a second and then closes. Does anyone know what I am doing wrong?
You have almost get it right. This is because the RAII of C++. If you allocate the Dialog on stack, it would be destructed as soon as the function return.
Assuming MainWindowImpl inherits publically from QWidget, you're looking for this:
void MainWindowImpl::add_rec()
{
// passing "this" to the constructor makes sure dialog will be cleaned up.
// Note that DialogImpl will need a constructor that takes a
// QObject* parent parameter.
DialogImpl* dialog = new DialogImpl(this);
dialog->show();
}
Look at the Qt documentation for examples of how the constructors should look.
Apparently QT4 only allows one instance of an object at a time, however pointers are another matter. Change both the main.cpp and what ever your main window to look something like this:
DialogImpl *dia=new DialogImpl;
dia->show();