How to use QCursor::pos() without using QApplication? - c++

I'm writing a project in Qt Creator, and if I write
QPoint cursorPos=QCursor::pos();
then cursorPos={-2147483648,-2147483648} which is obviously wrong. However, if I write
QApplication *application=new QApplication(argc,argv);
QPoint cursorPos=QCursor::pos();
then cursorPos is the correct mouse position. Is there any way I can get QCursor::pos() to work without QApplication? Thanks. :D

QApplication object does so much initialization. One of the QApplication's main areas of responsibility in the Qt documentation :
It manages the application's mouse cursor handling, see setOverrideCursor()
Also from the Qt documentation about QCursor :
Note: It is possible to create a QCursor before QGuiApplication, but
it is not useful except as a place-holder for a real QCursor created
after QGuiApplication. Attempting to use a QCursor that was created
before QGuiApplication will result in a crash.
So it seems that it is not possible to use QCursor without QApplication or QGuiApplication.

Related

need help in a Qt Creator C++ app using Open GL

I'm writing an app in Qt Creator, using C++. The eventual goal is to have control over an OpenGL window from within the Qt main winow.
Initialization is fine, both mainwindow and OpenGL window start up with no issues.
The mainwindow is subclassed from QMainwindow, the OpenGL window is subclassed from public QWindow, public QOpenGLFunctions.
Here's the crux of the problem. I want event handlers in mainwindow to have access to the OpenGLWindow. I can't seem to make that happen. I've gotten past a number of obstacles so at this point I have the following set-up;
In main.cpp, I declare the objects for both mainwindow and OpenGLWindow. I have the mainwindow mousepressed event handler in main.cpp. As is, all works fine. Both windows come up as they should, and the event handler code does exactly what I want it to do in the mainwindow, just print some text in a textbox.
In order to have access to the openglwindow from the event handler in main.cpp, I declare the OpenGLWindow object as global, outside of the main () main.cpp (is this bad technique?).
Everything compiles fine, but when I run it I get the error 'QPixmap: Must construct a QGuiApplication before a QPixmap'. I assume that this means that the system is not happy that I am creating the OpenGLWindow before the application object.
Is there a more elegant way to do this? Am I a few lines away from correct code, or does this need some major rearranging.
BTW - I am doing this in Windows 10. The main reason I have chosen Qt and OpenGL for this app is that I want it portable to Linux.

Qt: Access Widget from main function and implement exit button

I want to implement an exit button in my application, which has the following setup:
I have a main function which looks like this:
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
I also have a mainWindow function which has been generated by the QT Creator IDE.
I design the GUI with the Qt Designer and when I want a pushbutton to do something when clicked, I use a function like this:
void on_selection_clicked();
I hope the setup is now sufficiently described.
Now to my problem: I want to implement a button, which, when clicked, terminates the window and the application. I first tried implementing this in a function like this:
void on_exit_clicked();
But I don't know that to to here.
Then I heard of a aproach via QObject::connect, but I have two questions:
1.) Where should I put this? In the main function? 2.) can I access the object simply via the object name given in the QT Designer?
no you should connect it in the constructor of the MainWindow
connect(ui->exit,SIGNAL(clicked()),QCoreApplication::instance(), SLOT(exit()));
QCoreApplication::instance()->exit() will quit the application
yes through the ui field in MainWindow see the code above
I don't know which Qt version you use, so I will suppose Qt 5.0 (signal/slot mechanims was updated).
QWidget has slot QWidget::close().
QPushButton provides signal QPushButton::clicked(bool checked = false)
So you can connect them in constructor of your MainWindow:
QObject::connect(your_button, &QPushButton::clicked, this, &QWidget::close());
Also I suggest to look into the files generated from *.ui files - so you have deeper understanding of what's going on.

Using Qt To Build A Full Screen Layout

I am trying to use qt along with the qt designer to create a simple full screen webview with a line edit and a button above to create a really simple browser.
The problem is that the layout doesn't want to expand to fill all of the available space. I seem to think that I am missing something really simple, but I just can't seem to figure it out.
Here is an overview of my layout
<MainWindow>
<GridView>
<VBoxLayout>
<HBoxLayout>
<lineEdit /><PushButton />
</HBoxLayout>
<WebView />
</VBoxLayout>
</GridView>
</MainWindow>
Here is the code on the MainWindow Class
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit->showFullScreen();
ui->pushButton->showFullScreen();
ui->webView->load(QUrl("http://google.com"));
ui->webView->showFullScreen();
}
and here is the main code
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();
return a.exec();
}
It comes out looking like this instead of the webview and lineedit filling the whole amount of space
Is there anyway of doing this in Qt, I would have assumed that this was a standard thing to want to do.
Many Thanks in advance!
I think you have to replace the GridView by the VBoxLayout directly above.
What is the grid view you use exactly ?
<MainWindow>
<VBoxLayout>
<HBoxLayout>
<lineEdit /><PushButton />
</HBoxLayout>
<WebView />
</VBoxLayout>
</MainWindow>
Make sure your Object Property "sizePolicy" is set Maximum and "maximumSize" is 16777215, then w.showFullscreen should work
If you mean that you want the window to fill the entire screen, hiding the task bar and title bar, you should replace this:
w.showMaximized();
with this:
w.showFullScreen();
If you instead mean that you want your line edit and web view widgets to fill the window that contains them, "full screen" doesn't mean what you think it does. Your problem is probably related to your layouts in designer, and we don't have enough information in your original post to properly diagnose it. Given how simple your UI is at this point, the easiest thing to do is probably break all layouts and start over.
Whatever it is that you want, you definitely shouldn't be calling showFullScreen() on your line edit, push button, or web view.
I suspect the problem is that you've set up the BoxLayout inside the parent widget, rather than setting the parent widget to use a BoxLayout. In Qt Designer, you should be able to right-click on the parent widget and set the layout, and it will expand like you want. If you just add a BoxLayout to a widget from the toolbar, it won't automatically expand to match its parent.
See this link for more details: http://embrisk.com/notes/qt_resize.html
Expanding upon Stephen Bell's answer (I'd comment but I lack the reputation), as it took me awhile to figure this out as well.
If you have completely designed the layout you wish to have fullscreen, right-click on the "Main Window" in the far right of the screen. A pull-down should appear. Click Layout, then Grid Layout. Main Window should assume a grid layout. It should not change the positioning of your objects at all in Qt Designer. Yet, it should fix the fullscreen.
If MainWindow does not have a layout, your layout will likely have whitespace or deadspace without an explanation.

Using a QT window as part of a C++ unit test

I have some code which uses WinAPI to get the title and classname of a window from it's handle using GetWindowTextW and GetClassNameW. I would like to create a unit test for this code using Qt to create a temporary window, run my code against it, and then close the window. However I'm unsure how to go about doing this in a simple way. For example, I could create the window as follows:
#include "QtWidgets\qapplication.h"
#include "QtWidgets\qtextedit.h"
int argc = 1;
char* argv[1];
QApplication app(argc, &argv[0]);
QTextEdit textEdit;
textEdit.show();
app.exec(;)
// Rest of my unit test here
However at that point the QApplication object enters it's event loop and assumes control of my unit test until I close the window. What is the best way to allow my unit test to continue operating on the window? Should I create a separate thread for the window? Being a unit test, I would like to keep it as simple as possible.
This question is intended to be unit test framework independent, but in case it matters, I'm using UnitTest++.
You won't be able to create a separate thread, since all Qt gui objects have to be in the main thread, you can only use signals/slot mechanism to interact with gui objects from other threads.
I think the simplest would be to subclass QTextEdit, implement public slot UnitTest(), and modify your test as follows:
#include "QtWidgets\qapplication.h"
#include "QtWidgets\qtextedit.h"
#include "MyTextEdit.h"
#include <QTimer>
int argc = 1;
char* argv[1];
QApplication app(argc, &argv[0]);
my_QTextEdit textEdit;
textEdit.show();
QTimer::singleShot(&my_QTextEdit,SLOT(UnitTest()),0);
app.exec();
This gives you an entry point to my_QTextEdit::UnitTest() after QApplication is properly instantiated and event loop is running. Or, you can implement your own class inherited from QObject, create public slot, create that object prior to running app.exec() (passing to it pointer to QTextEdit if necessary) ; and connect to the slot the same way - whatever suits your needs better.
In my automated Qt tests, I generally skip the use of QApplication::exec in favour of using QCoreApplication::hasPendingEvents and QCoreApplication::processEvents - this lets you do some prep work, flush the event queue (so Qt gets a chance to actually show your window), do some more work, let Qt handle any additional events that this has thrown up, etc; it's a very handy approach for achieving the fine-grained control you need when you want to exercise small pieces of logic.
reasonably working example code for doing this is in this related question's answer: Qt event loop and unit testing?

What did QWidget* QApplication::mainWidget() become in Qt4?

I am porting an application from Qt3 to Qt4, and need a Qt4 replacement for QApplication::mainWidget() which used to return the top-level widget in Qt3. Does anyone know how to do this in Qt4?
Technically, any widget initialized with NULL is a top level widget so QApplication shouldn't assume that one of them is better than another.
The way I usually do it is to save a pointer to the "real" main widget somewhere, even a global variable or a singleton and reference it when needed.
I think topLevelWidgets() is as close at it can be.
Edit:
Yup. Qt4 added complexity (and power). There is no application wide MainWidget anymore. Many QMainWindows can be created and shown, and hidden, and shown again. This is a good thing, though :)
As shoosh noticed, QT3 behaviour can be easily simulated with global variable (yuck!) or QApplication subclass.
I think what you're looking for has been replaced by the QMainWindow class, which does allow you to set a set and get a central widget.