Qt: maximized frame - c++

I have a beginner question. I'm trying to create a maximized QFrame with the following code but I'm receiving an error which says:
error C3867: 'QWidget::showMaximized': function call missing argument list; use '&QWidget::showMaximized' to create a pointer to member
Code:
class FrameWindow{
private:
QDesktopWidget *desktop;
QFrame frame_window;
QRect frame_rect;
public:
FrameWindow(QApplication& app){
desktop = app.desktop();
desktop->showMaximized;
frame_window.setWindowTitle("QT Trainning");
frame_window.show();
}
I'm totally beginner in C++, so what I'm missing please?

functions/methods generally need argument list, even an empty one -> object->method() Try using brackets.
You eventually want:
w->setWindowState(w->windowState() | Qt::WindowFullScreen);
Edit:
or as your solution:
w->setWindowState(w->windowState() | Qt::WindowMaximized);

In addition to what others have already noticed, it's completely counterproductive to pass either the current application or to hold a pointer to the desktop. The application pointer is always available via the global qApp macro. To get the desktop, simply use
qApp->desktop()
There is absolutely no reason to "cache" this value. Get it whenever you need it, that's all.
It'd be also more idiomatic to derive from the widget type, instead of holding it as a member. The code could be simplified as below. It is a complete, self-contained example.
#include <QFrame>
#include <QApplication>
class FrameWindow : public QFrame {
public:
FrameWindow(QWidget * parent = 0, Qt::WindowFlags * flags = 0) :
QFrame(parent, flags)
{
setWindowTitle("Qt Training");
setWindowState(windowState() | Qt::WindowMaximized);
}
};
int main(int argc, char ** argv) {
QApplication app(argc, argv);
FrameWindow fw; // constructor is called here
fw.show();
return app.exec();
// FrameWindow::~FrameWindow() destructor is called first before exiting
// QApplication::~QApplication() destructor is called next
}

Related

Qt GUI Easiest way to access MainWindow from another class

I am doing a blackjack program and I am keeping track of the cards in the players hand in another class ("hand.h") than the main window class.
In the hand class, for every card that I collect, I am also creating a QLabel that grabs the proper card image for the card and also sets the coordinates for where the card should appear on the main window.
The problem is that I am not able to create the QLabel based on the MainWindows object that is originally created at the main function. Is there any easy way that I am able to get that information fairly easily? Thanks for your help!
I have tried using QGuiApplication::topLevelWindows(), but haven't came to luck with using that. Here is my function that I am using.
#include <QRect>
#include <QApplication>
#include <iostream>
#include <QLabel>
#include "mainwindow.h"
#include <QMainWindow>
#include <QWindowList>
#include <QWidgetList>
#include "ui_mainwindow.h"
void Test() {
QList<QWindow*> Main_Window = QGuiApplication::topLevelWindows();
for (int i = 0; i < Main_Window.size(); ++i) {
if(Main_Window.objectName() == "mainWindow") // name is OK
break;
}
QMainWindow* mainWindow = static_cast<QMainWindow*>(Main_Window);
QLabel* temp;
temp = new QLabel(Main_Window);
temp->setPixmap(QString("Ten of Clubs.png"));
temp->setGeometry(290, 300, 350, 390);
temp->show();
}
Here is the main.cpp file that creates the mainwindow
int main(int argc, char *argv[])
{
srand(time(NULL));
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
I found the iterating code online and have been having issues from it.
I am having issues while trying to iterate through the list, but I have no idea how to identify the list and the error says that there is no objectName() function. Also, in the static cast line, there is an error that says that I cannot convert an QList to type QMainWindow. Any help would be greatly appreciated.
No way in general, because some applications may have several (toplevel) QMainWindow-s (and their list could change with time). So for that case you'll better pass the pointer to it (the particular QMainWindow you want to deal with) explicitly....
A possible way might be to have your specific subclass of QApplication (which is a singleton class, see QCoreApplication::instance to get its sole instance) and in your application subclass put, as fields, the explicit windows you want to deal with (maybe you even want to add some new signal or slot to your application class).
However, you could use QGuiApplication::topLevelWindows() or QGuiApplication::allWindows() to get the list of all such windows. Notice that a QWindowList is just a QList<QWindow *>. So see QList for how to traverse or iterate on that list.
Once you have found which QMainWindow you want, adding a QLabel into it is usual practice (but again, signals & slots could be helpful).
BTW, each (displayed) widget has its window, see QWidget::window()
About your code:
Your Main_Window is really poorly named (and the name is so confusing that I cannot use that). It is a list not a window. So code first:
QMainWindow* mainWindow = nullptr;
{
QList<QWindow*> topwinlist = QGuiApplication::topLevelWindows();
int nbtopwin = topwinlist.size();
for (int ix=0; ix<nbtopwin; ix++) {
QWindow*curwin = topwinlist.at(ix);
if (curwin->objectName() == "mainWindow")
mainWindow = dynamic_cast<QMainWindow*>(curwin);
}
}
I did not test the above code and I am not sure it is correct or even can compile. But why don't you just have a global pointer to your main window:
MainWindow*mymainwinp = nullptr;
and initialize it appropriately in your main body:
int main(int argc, char *argv[]) {
srand(time(NULL));
QApplication a(argc, argv);
MainWindow w;
mymainwinp = &w;
w.show();
int r = a.exec();
mymainwinp = nullptr;
return r;
}
then use mymainwinp elsewhere (e.g. in your Test)? If you want more elegant code, define your own subclass of QApplication and have mymainwinp be a field in it.

Qt/C++ : Centralise parameters in one class

I'm trying to centralise some parameters in one class. I looked on several forums and tutorials without finding any real answer. Maybe I don't use Qt correctly.
I have a Qt class Application which handles theses parameters.
Application.h
class Application : public QApplication
{
public:
Application(int, char**);
~Application();
bool setFilesPath(QString path);
QString getFilesPath();
private:
QString filesPath;
}
main.cpp
int main(int argc, char *argv[])
{
Application app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
I'd like to access the setFilesPath() and getFilesPath() methods from everywhere (for exemple in another class. Therefore a made Application inherit from QApplication, hoping that qApp.setFilesPath() would work. But it doesnt.
It seems to be a quite usual thing to access some parameters from everywhere. So how could one do this ?
I've found this three ways :
Global variables
Static methods
Including an instance of Application in every class needing the method (but it seems wrong)
Which is more commonly used (and why) ? Why does my way doesn't work ?
Thank you.
EDIT:
In this topic, they use singelton design pattern.
So calling
Application *app = Application::getInstance();
everywhere I need it. Is it better ?
You can access your class using qApp pointer. According to the Qt documentation:
A global pointer referring to the unique application object. It is
equivalent to the pointer returned by the QCoreApplication::instance()
function except that, in GUI applications, it is a pointer to a
QApplication instance.
So, your code somewhere could look like:
Application *myApp = qobject_cast<Application *>(qApp);
QString path = myApp->getFilesPath();
You can have your classes in the main independently and connect a signal from each class that needs to access the value in your class to the slot that returns the value :
int main(int argc, char *argv[])
{
Application app(argc, argv);
MainWindow mainWindow;
MyClass myclass1;
QObject::connect(&mainWindow,SIGNAL(askFilesPath()),myclass1,SLOT(getFilesPath()));
mainWindow.show();
return app.exec();
}
This way when you call the signal askFilesPath() in your MainWindow, the slot in your custom class gets called and the value is returned:
QString filePath = askFilesPath();
You should note that if the two classes are in different threads then the connection type should be Qt::BlockingQueuedConnection.

Must construct a QApplication before a QWidget

Everywhere only just "before QPaintDevice" questions and nowhere is my error. So, here we go.
I need an extern QWidget to be able to get access to it from outside (because I don't know any other ways to do it). Basically, I need this: Create 2 QWidgets from 1 window, go to first window and from there hide main window and show second window created by main window (although main window is not main(), it is QWidget too).
I added
extern QWidget *widget = new QWidget
everywhere and everyhow in possible ways, and I still got this message. I suppose, it means that I need to create my QApplication (in main.cpp) and only then declare any QWidgets. But then HOW can I access those QWidgets from another QWidgets?
Code is here:
https://github.com/ewancoder/game/tree/QWidget_before_QApp_problem
P.S. The final goal is to be able show and hide both gamewindow.cpp and world.cpp from battle.cpp (just regular class)
And btw, adding Q_OBJECT and #include both don't work.
Anyway, if I cannot use functions from one window to another, than what's the point? I can have one window in another, and then another in that one, and then one in that another... but I can't do anything from the last to the previous. After years on Delphi that seems strange to me.
Don't use extern or otherwise static variables which lead to creation of the widget before the QApplication is created in main. The QApplication must exist before the constructor of the QWidget is executed.
Instead of sharing the variable via extern, either make the other windows members of the main window, and then make the windows known to each other by passing around pointers, or keep them private in MainWindow and request the actions from the subwindows e.g. via signal/slots. As a generic rule, don't use global variables but class members.
In the following FirstWindow (which is supposed hide main window and secondWindow) gets the main window and the second window passed via pointers and then just calls show/hide on them directly.
int main(int argc, char **argv) {
QApplication app(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return app.exec();
}
In main window, have two members for the two other windows, say FirstWindow and SecondWindow:
class MainWindow : public QMainWindow {
...
private:
FirstWindow *m_firstWindow;
SecondWindow *m_secondWindow;
};
MainWindow::MainWindow(QWidget *parent) {
m_firstWindow = new FirstWindow; //not pass this as parent as you want to hide the main window while the others are visible)
m_secondWindow = new SecondWindow;
m_firstWindow->setMainWindow(this);
m_firstWindow->setSecond(m_secondWindow);
m_firstWindow->show(); //Show first window immediately, leave second window hidden
}
MainWindow::~MainWindow() {
//Manual deletion is necessary as no parent is passed. Alternatively, use QScopedPointer
delete m_firstWindow;
delete m_secondWindow;
}
FirstWindow, inline for brevity:
class FirstWindow : public QWidget {
Q_OBJECT
public:
explicit FirstWindow(QWidget *parent = 0) : QWidget(parent) {}
void setMainWindow(MainWindow *mainWindow) { m_mainWindow = mainWindow); }
void setSecondWindow(SecondWindow *secondWindow) { m_secondWindow = secondWindow; }
private Q_SLOTS:
void somethingHappened() { //e.g. some button was clicked
m_mainWindow->hide();
m_secondWindow->show();
}
private:
MainWindow* m_mainWindow;
SecondWindow* m_secondWindow;
};
Maybe not helping the former author, but others facing the problem.
I simply got this error by mistaking a debug-library with a release one. So check your linker settings, if you are sure the implementation is done right (first instancing application and then using widgets).

Invalid use of 'this' in non-member

I have a problem - discussed a lot previously, but all solutions I saw doesn't work here.
What is wrong in this code?
main.cpp:8:19: error: invalid use of ‘this’ in non-member function
#include <QApplication>
#include <QPainter>
#include <math.h>
class QPainter;
int main(int argc, char *argv[]){
QApplication app(argc,argv);
QPainter painter(this);
painter.setPen(QPen(Qt::black,3));
int n=8;
for (int i=0;i<n;++i){
qreal fAngle=2*3.14*i/n;
qreal x = 50 + cos(fAngle)*40;
qreal y = 50 + sin(fAngle)*40;
painter.drawPoint(QPointF(x,y));
}
return app.exec();
}
In the function "main" you are using the reserved keyword "this" which means "address of the current object". main is a function and not a member of any class or object that would have a "this" variable. I know nothing about qt but 5 seconds with google tells me that "QPainter" wants the address of a QPaintDevice.
http://qt-project.org/doc/qt-5.0/qtgui/qpainter.html#QPainter
If you are talking about QPainter painter(this); you are using the this pointer in main. The this pointer is for member functions of an object. Your main function doesn't have a this pointer to use.
In Qt you need to create a window (inheriting from QWidget) before you can see anything on the screen. You then create a QPainter object inside the paintEvent method of your window and there you will have the proper this to pass to QPainter constructor.
You're highly encouraged to follow some tutorial. Qt is fantastic, but it's huge and it's not a library, but a framework (like most other GUIs).
Your code must be structured in a quite specific way.
You just tried to copy some code without understanding what was going on.
It looks like you saw a code like this :
#include <QtGui>
#include <QWidget>
class MyWidget : public QWidget
{
Q_OBJECT
public:
protected:
void paintEvent(QPaintEvent *event)
{
//create a QPainter and pass a pointer to the device.
//A paint device can be a QWidget, a QPixmap or a QImage
QPainter painter(this); // <- Look at this !!
// ^^^^ Allowed
// ...
}
signals:
public slots:
};
int main( int argc, char **argv )
{
QApplication app( argc, argv );
MyWidget myWidget;
myWidget.show();
return app.exec();
}
Here you can see that in the function paintEvent of the class MyWidget we use the this pointer. We can because we use it in a non-static member of the class. Here this is of type MyWidget*.
Look at the standard :
9.3.2 The this pointer [class.this]
In the body of a non-static member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called. The type of this in a member function of a class X is X*.
So you cannot use the this pointer inside the main function, this is no sense.
And other thing, like it is said in the comment inside the code, you just have to pass a pointer to a device to the QPainter constructor. It can be a QWidget, a QPixmap or a QImage.
Maybe you should read this for a beginning : http://www.cplusplus.com/doc/tutorial/classes/

GTKMM Error: Void Value Not Ignored As it Ought to Be

I am trying to create a simple window in GTKMM that contains a box. I've got the window part working, but I can't get my box code to work. I am following along with this tutorial
I think the tutorial is a little bit dated because Anjuta (the IDE I'm using) generated some different code. Here is my code that should add a box:
#include <gtkmm.h>
#include <iostream>
#include "config.h"
using namespace Gtk;
int main (int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window *main_win = new Gtk::Window (Gtk::WINDOW_TOPLEVEL);
main_win->set_title ("Image-Viewer");
Gtk::Box *box = Gtk::manage (new Gtk::Box());
box ->set_orientation (ORIENTATION_VERTICAL);
box->set_spacing(6);
*main_win -> add(*box);
if (main_win)
{
kit.run(*main_win);
}
return 0;
}
In the code on the tutorial the window is not created in the same way. As you can see below, the window in my code is being created so that it is in the heap, rather than the stack. (or at least I think [I am new to C++]). I know that items in the heap should be used like a pointer, so for the add function I did that, (rather than using the dot notation described in the tutorial). When I run this code, I get an error stating the following:
error:void value not ignored as it out to be
The error is pertaining to the add method being called on the window. Can somone tell me what I'm doing incorrectly? Thanks
This instruction:
Gtk::Window *main_win = new Gtk::Window (Gtk::WINDOW_TOPLEVEL);
Declares a pointer to Gtk::Window. Later, you do:
*main_win -> add(*box);
This is incorrect, because you basically try to apply operator -> after you already dereferenced the main_win pointer - and the result of this dereferencing is not a pointer itself, but a reference to an object of type Gtk::Window.
To fix the problem, remove the extra dereferencing:
main_win -> add(*box);
NOTE:
I do not know Gtk::Window and its member function add(), but if it is the case that add() accepts a pointer as its argument, then you also shouldn't dereference box.