I've seen example of QApplication::notify usage here: How to detect if a Qt GUI application has been idle, inside the app itself (Qt)?
I need to do the same without basing QApplication method. qApp has connectNotify method so I suppose it should be possible just to make own action on notify signal.
If that is possible I need basic example how can I connect to this event.
Maybe you should have a look at event filters, which you can install for all QObjects: QObject::installEventFilter.
Write your own class, which you inherit from QObject and implement the eventFilter method, where you insert your event processing logic.
Then install an object of this class to your QApplication instance (qApp for example)
Related
Using Boost Unit Test framework to perform unit test on C++\Qt code.
We are basically using BOOST_FIXTURE_TEST_CASE macro as shown in documentation. For each test we create an instance of QApplication to setup the event loop and enable the test code to use signals and slots.
Now we need to test whether a signal is emitted or not. Does anyone have any experience with this issue?
The BOOST_FIXTURE_TEST_CASE generated class does not inlucde Q_OBJECT and does not derived from QObject which I guess would be a problem. Appreciate some input on this issue.
I'm working on a similar issue, but using gtest rather than the Boost Unit Test framework. While I don't have the answer yet I am making progress, here is what I know so far.
First of all, Qt does not like it when QApplication or QCoreApplication are generated outside of main. Also, QApplication applies to GUI classes of Qt, while QCoreApplication can be used for console only classes (like QTcpSocket which is what I am trying to test now). GUI stuff is not really testable, so anything you are testing should be written into a separate class. This will allow you to unit test your code without dealing with the GUI, and also let you use QCoreApplication.
The next step is to use QThread to spin up a thread that hosts the object you are trying to test. QThread has its own event loop that can be run by calling its exec() function.
Write your test cases to pull from QThread and you'll have an event loop that you can use for the signals and slots, which should make it much easier to determine if a signal was emitted. Without the event loop the signal will just sit there and do nothing, so there is no way to test if it was sent!
The application I'm working on is made of many C threads communicating together via messages (0mq). One of these threads is handling the display and should render off screen a widget in order to communicate its "screenshot" to other threads of the application.
The thing is that in order to paint a widget, you need to place it in a QApplication and call the exec() method of the QApplication, which is essentially a loop. So my thread is then completely stuck and can't communicate with the outside world anymore since it's in the exec() method.
Is there a way I can launch the QApplication in a separate thread and communicate with it so my display thread doesn't get stuck?
Or is there at least a way to do what I want to do with Qt?
Thanks a lot !
Edit: This application will eventually be a Qt Embedded Application
Update Basically, my question is : how to start a QApplication in a separate thread from my C code and communicate with it?
I ended up creating a separate thread for the QApplication main event loop (exec()) and used 0mq sockets to communicate with it from the rest of my application.
I don't understand what do you mean by "paint a widget". But be aware: QWidget is a part of GUI and GUI parts should be touched by Main(UI) thread only. It is a rule you can't change. Moreover QApplication works on Main thread only since QApplication is the main part of the GUI itself.
You can post messages to QAppplication by using global qApp object(you need to include QApplication for it) and sendEvent() or postEvent() methods.
Also I'd suggest you to generate QImage with whatever data you have and propagate it via aforementioned event mechanism to the widget you need. But, obviously, I don't know what you really need.
I have created a set of watcher/helper classes that monitor an outside application, and I would like these to print to a log window inside my MainWindow's ui when changes are made. My idea was to create this watcher inside a thread in main, but I am not sure the best way to link it to my MainWindow. I know that simply passing it as below will not work, but am unsure of the proper way to do this, if there even is one, because of Qt's design. Some research indicated to me that it isn't really appropriate to pass MainWindow to an outside class, but I am unsure of a better way to do it.
int main(int argc, char *argv[])
{
try {
std::string host = "localhost";
unsigned short port = 8193;
MainWindow w;
w.show();
// Access class for the program that I am watching
UserInterface ui(host, port);
// StatePrinter class, which is registered in the UI and will print changes to MainWindow, ideally
// would I be able to pass something in the StatePrinter constructor to accomplish my goal?
ui.registerObserver(new StatePrinter(w));
UiRunner runner(ui);
boost::thread runnerThread(boost::ref(runner));
w.show();
QApplication a(argc, argv);
runner.cancel();
runnerThread.join();
return a.exec();
} catch(std::exception &ex) {
// ...
}
}
I suppose it is a possibility to make this thread inside MainWindow itself, but I prefer having it in main. What would be the best way to link my StatePrinter class to MainWindow?
You could make your watcher class a QObject itself, push it into a thread, and make it emit signals when it "notices" changes that you want to log with the log informations as the signal parameters.
Then, you could push this object in a QThread as follow :
QThread* thread = new QThread();
ui->moveToThread(thread);
//Create the needed connections
thread->start();
Depending on what you need, you may connect a signal to the thread's start() slot instead of calling it directly. (Read this to know which connections you'll need with your thread so it is started, stopped and cleaned correctly).
You have several problems:
Creating widgets before instance of QApplication
runnerThread.join call will block main Qt thread before entering Qt event loop - so your GUI will be freezed
You should implement notification system to watch for termination of boost threads. But better solution is to use Qt threads.
You should create first class - "watcher" with neccessary signals.
Then create second class with UI logic and neccessaty slots
Then connect signals to slots
Profit!
Look at Qt documentation about QThread - there are simple samples.
As far as the GUI designer, I understand how certain signals affect certain slots and invoke code. Other than that method, I am unsure about how to invoke a slot from a signal.
Take this example:
void QFileDialog::directoryEntered ( const QString & directory ) [signal]
This is a signal. When the directory is entered, I want this to populate a widget QColumnView with the contents of the directory.
How does a non widget signal invoke a slot of a UI widget.
I assume you use connect but the example provided uses two separate objects.
Signals and slots are features of QObject. It works well even for non-GUI code.
Connecting a signal to a slot is always done through the connect function:
connect(myDialog, SIGNAL(directoryEntered(QString)),
this, SLOT(updateColumn(QString)));
here assuming that you have updateColumn() slot in your main object handling the actual UI update of that QColumnView.
I am new to Qt GUI programming and come from a .NET/Winforms background as far as GUI development goes. I am using the Qt Creator IDE.
How can I handle a button press event in Qt to do something like the following:
if (button.clicked = true)
{
startProgram();
}
Also, how would I browse for a configuration file which would populate values into all of my line edit textboxes when opened? I am programming this in C++.
EDIT: I am taking a console app that someone else wrote and building a GUI around it. I want to access one of the functions in there from a button click event. However, I can't figure out how to get the functions of the original app to be in scope of the GUI which I have created when I try to use SIGNALS and SLOTS.
A simple example could be something like this. Say you have a class like ProgramStarter:
#include <QObject>
class ProgramStarter : public QObject {
Q_OBJECT
public slots:
void startProgram() {
//Do stuff
}
};
and something like this where ProgramStarter is used:
#include <QtGui/QApplication>
#include <QPushButton>
#include <QObject>
#include "programstarter.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton *testButton = new QPushButton("Push me");
testButton->resize(100, 40);
testButton->show();
ProgramStarter *program = new ProgramStarter;
QObject::connect(testButton, SIGNAL(clicked()), program, SLOT(startProgram()));
return app.exec();
}
Qt uses signals and slots to communicate between objects. The core idea is that signals are emitted when events occur and these signals can be connected to slots. In this case the button emits a clicked() signal when the button is pressed and the clicked() signal is connected to the startProgram() slot. So when the button is pressed, startProgram() is called.
Qt has a meta-object system for enabling the use of signals and slots, among other things. This is the reason why ProgramStarter inherits QObject and why the Q_OBJECT macro is in the header. I highly suggest reading this if you want to understand how signals and slots and the meta-object system work in Qt: http://doc.qt.io/qt-5/signalsandslots.html
It's a little long to explain but you connect the signal from the button to the slot with the function.
connect(button, SIGNAL(triggered()), this, SLOT(doSomething()));
You really need to read and understand signals and slots before trying to write code
edit: You are trying to call functions in a compiled separate running program?
Are you confusing Qt Signals with C/Unix signals? You could start the separate app from within your Qt app, get its PID and then send it a 'c' signal.
Or if you have the source of the app you could include it's code into your Qt app and then call any of the functions by simply wrapping them with a Qt slot handler.
In order to access the functions defined in the console application, you need to include the headers (.h/.hpp) that declare these functions, and link their implementation. I you have the source code of the implementations (.cpp), you need to add them to the sources to be compiled (they will be compiled in object files (.o) that will be linked in the final executable). If the console application is a front-end to a set of functions defined in a library (.lib, .a), you need to link this library.
After that, you can use Qt's signal/slot mechanism to connect the "button clicked" signal to a slot calling the function you want to execute, as described in other answers.
It seems like your problem is not really to do with Qt or GUI programming at all, but rather a general design issue. Others have told you how to be notified when the button is pressed - it's up to you to hook that notification up to whatever code you want to call. Some possibilities:
If you just need to call a function then include the appropriate header file and call it.
If you have an object you want to call a method on, then you will need to provide a reference to that object to the class which receives the notification.
If your console app is a separate program, you can use QProcess to launch and communicate with it.
I guess your problem is that you cannot call the console app's function, because it hasn't been defined to be a slot. So here is how you might do it.
Let's assume you have a console app class which might look like this:
class ConsoleApp
{
public:
void run()
{
// Code which you want to trigger by a button in your UI.
}
}
Then we implement a Qt based wrapper class which inherits from QObject class and, hence, is able to send and receive signals. This class simply provides a custom slot which delegates execution to the ConsoleApp class.
class ConsoleAppWrapper : public QObject
{
Q_OBJECT
public slots:
void startProgram()
{
m_consoleApp.run();
}
private:
ConsoleApp m_consoleApp;
}
Ok, and now we want a button which, when pressed, will trigger a call of the 'run()' method.
int main(int argc, const char** argv)
{
QApplication app(argc, argv);
// Define wrapper for console app.
ConsoleAppWrapper wrapper;
// Define button and connect its 'clicked()' signal
// to the wrapper's 'startProgram()' slot.
QPushButton startProgramButton("Start Program");
connect(&startProgramButton, SIGNAL(clicked()), &wrapper, SLOT(startProgram()));
// Show the button.
startProgramButton.setVisible(true);
// Start Qt's event loop.
app.exec();
}
This should give you a 'Start Program' button which, when pressed, will call ConsoleApp::run() method.
While this example is not Qt Designer based I hope this example helps you hunderstand how signals and slots work in Qt.
Cheers,
Jonny
If you have a button created with the Designer you can use on_myButton_clicked() slot in the parent widget class, just like in WinForms.