First this is my first development using bb10 sdk and also with qml + c++, I had
I'm trying to capture the moment when the user slids from the blackberry logo, to minimize or switch app. Acording to their official documentation http://developer.blackberry.com/native/documentation/core/com.qnx.doc.native_sdk.devguide/com.qnx.doc.native_sdk.devguide/topic/c_appfund_applifecycle.html
There is a state windows NAVIGATOR_WINDOW_INACTIVE that comes when the invisible() method is called,
the thing here: is that the documentation and searches I've done on internet, doesn't explain anything about were to override a method that listens for this event.
Any help would be greatly appreciated.
You need to create a subclass of QObject. If you use the project creation wizard Momentics will do this for you as applicationui.hpp and applicationui.cpp. In this class declare the following slots in application.hpp:
public slots:
void asleep();
void awake();
void invisible();
void thumbnail();
void fullscreen();
Then in the class creation function attach the Application signals to your slots:
bool c = QObject::connect(Application::instance(), SIGNAL(asleep()),
this, SLOT(asleep()));
Q_ASSERT(c);
c = QObject::connect(Application::instance(), SIGNAL(awake()),
this, SLOT(awake()));
Q_ASSERT(c);
c = QObject::connect(Application::instance(),
SIGNAL(invisible()), this, SLOT(invisible()));
Q_ASSERT(c);
c = QObject::connect(Application::instance(),
SIGNAL(thumbnail()), this, SLOT(thumbnail()));
Q_ASSERT(c);
c = QObject::connect(Application::instance(),
SIGNAL(fullscreen()), this, SLOT(fullscreen()));
Q_ASSERT(c);
Q_UNUSED(c);
Then define the slot functions to perform what you need to do when the application state changes into the one corresponding to the signal (I've only included one here):
void applicationui::asleep() {
//configure application for sleep mode. Suspend or reduce processing, etc.
}
Related
I've got an assignment to create sort of a multi-platform C++ GUI library. It wraps different GUI frameworks on different platforms. The library itself provides an interface via which the user communicates uniformly (using the same code) regardless of the platform he's using - typically it's MFC on Windows and Qt elsewhere.
Currently, I'm stuck on messages/events. So far, I've been using MFC messages and Qt signals to get notified of the user's interaction and had no problems with that. The user creates a list box (which contains p_lb - pointer subclassed QListWidget on Qt or CListBox on MFC) and then he ties his own DoSomething() handler with an event.
User's code:
ListBox lb;
lb.AddDoubleClickHandler([](int i) { DoSomething(i); });
This is what it looks like in the library:
// p_lb represents platform list box - QListWidget/CListBox
// handler's int parameter represents the index of the item, that has been double-clicked
void ListBox::AddDoubleClickHandler(const std::function<void(int)>& handler) {
#ifdef _MFC_PLATFORM
// only pushes the handler into the internal list
p_lb->double_click_handlers_.push_back(handler);
#elif _QT_PLATFORM
p_lb->connect(p_lb, &QListWidget::itemDoubleClicked, p_lb,
[handler, p_lb](QListWidgetItem* item) { handler(p_lb->row(item)); });
#endif
}
In MFC I need to call the handlers stored in the list manually:
#ifdef _MFC_PLATFORM
class MyMFCListBox : public CListBox {
public:
std::list<std::function<void(int)>> double_click_handlers_;
afx_msg void OnItemDoubleClick() {
for (const auto& h : double_click_handlers_) {
h(GetCaretIndex()); // call user's stored handler when the event occurs
}
}
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(MyMFCListBox, CListBox)
ON_CONTROL_REFLECT(LBN_DBLCLK, &MyMFCListBox::OnItemDoubleClick)
END_MESSAGE_MAP()
#endif // _MFC_PLATFORM
As I said, this works fine, but now I need to be able to notify UI control about some external event manually (and asynchronously) - using something like MFC's PostMessage. The use case would be something like updating progress bar based on some external computing (which is not necessarily done using this library). E.g. I'm uploading some photos, after each one of them I send a message to the ProgressBar about the current number of uploaded photos and number of all the photos, but I return immediately without waiting for the handler to execute. Also, there needs to be a way of adding new custom events by the user. I know that Qt has a similar method - postEvent, but is this the right way to implement it? Or should I implement my own signal-slot system? I cannot imagine how this would work. Any suggestions are appreciated.
I'm making a Qt frontend for a Rust libary which exposes a C++ function that blocks the execution thread it resides in, but allows to pass a callback function for communication between the two ends.
So I thought of using Qt's threading technologies to make the library execution on another thread, and I'd like to do it with the least amount of modifications as possible to the Rust library.
This is my approach using QThreads:
backend.cpp:
typedef void(*callback_t)(void *,const char *);
extern "C" call_rust_library(const char *config, void *cb_data, callback_t cb);
template<typename T>
void call_wrapper(void *ptr, const char*data) {
(*static_cast<T*>(ptr))(data);
}
class BackEnd : public QObject {
Q_OBJECT
public slots:
void do_computations(ConfigObject *config) {
//...parse configuration from the frontend...
char* parsed_configuration;
BackEnd* backend = this;
auto callback = [backend](char* data) {
//...process obtained data from the library...
QString type,contents;
backend->emit send_message(type,contents);
}
call_rust_library(parsed_configuration,(void *)&callback,call_wrapper<decltype(callback)>);
}
signals:
void send_message(QString type, QString contents);
}
frontend.cpp:
class FrontEnd : public QMainWindow {
Q_OBJECT
QThread thread;
ConfigObject *config;
public slots:
void process_message(QString type, QString contents) {
//...do GUI things with the message
}
private slots:
void on_request_start_thread() {
// called by a GUI event
BackEnd* backend = new BackEnd;
backend->moveToThread(&thread);
connect(&thread,&QThread::finished,backend,&QObject::deleteLater);
connect(this,&FrontEnd::run_thread,backend,&BackEnd::do_computations);
connect(backend,&BackEnd::send_message,frontend,&FrontEnd::process_message);
emit run_thread(config)
}
signals:
void run_thread(ConfigObject *config);
}
However I have a couple of problems with this:
First off, nothing from the backend gets executed. If I don't move the BackEnd object to another thread it does seem to run everything but crashes somewhere on a system library (my best guess is that is because Qt forbids blocking the GUI thread and/or handling GUI functions from another thread).
How would Qt be able to abort the Rust library execution thread? (via closing the application or the user clicking a button) The Rust library doesn't seem to expose any mechanism to stop its execution, so I'm wondering if I have to make modifications to the library to expose a function to abort whatever it's doing.
Recently I've found this example repository that allows for binding Qt with Rust libraries but doesn't seem to delve into multithreading, and might require my project to be ported from CMake to qmake. But from my understanding the Rust executions should be residing in another thread, so I'm not sure how is it achieved here.
The implementation is correct, save for the fact that I forgot a thread->start() call at the end of on_request_thread() function.
The crash happened because of a problem while parsing the ConfigObject, so it had nothing to do with the making of a thread.
I have some labels and layouts nested inside a QWidget to build a part of a sidebar. Each QWidget is its own section and one component currently looks like this:
To my understanding, you can only set hyperlinks with QLabel, but I'm trying to get the whole area between the white lines clickable. This is including the icon and the whitespace. Is there any way to achieve this?
This got marked as a duplicate to the opposite of what I was asking, so I'd like to reiterate that I'm trying to implement a hyperlink without QLabel.
You can easily have a widget open a link on click:
class Link : public QWidget {
Q_OBJECT
public:
Link(QUrl url, QWidget p = nullptr) : QWidget(p), _url(url) {}
QUrl _url;
void mouseReleaseEvent(QMouseEvent *) { QDesktopServices::openUrl(_url); }
}
You can avoid any extra signals and connections, and have each link widget store its own link internally, the url can be set on construction and changed at any time. Not using signals and slots makes it easier to change the link too, without having to disconnect previous connections.
IMO going for a signals and slots solution is only justified when you want different arbitrary behavior. In this case you always want the same - to open a particular link, so you might as well hardcode that and go for an easier and more computationally efficient solution.
I would just manually catch the SIGNAL for clicked() and use desktop services to open the url in code.
bool QDesktopServices::openUrl ( const QUrl & url ) [static]
Opens the given url in the appropriate Web browser for the user's desktop environment, and returns true if successful; otherwise returns false.
http://doc.qt.io/qt-4.8/signalsandslots.html
Using this type of syntax, or in the designer, you can also connect a signal to a slot.
connect(widgetThatRepresentsURL, SIGNAL(clicked()),
handlerThatWillOpenTheURL, SLOT(clicked_on_url()));
For widgets that don't have a signal set up for clicked (or whatever event you are interested in), you can subclass the widget in question and reimplement...
void QWidget::mousePressEvent ( QMouseEvent * event ) [virtual protected]
Specifically for creating a signal, there is emit. I've used this in the past like the following
void Cell::focusInEvent(QFocusEvent *e)
{
emit focus(this, true);
QLineEdit::focusInEvent(e);
}
with the following in the header
signals:
void focus(Cell *, bool);
I am working on a Desktop (Windows 7) based application and using Qt Creator v 5.6.0 for development of the Program.
I have a very strange issue i.e.
My Program crashes in DEBUG mode but works fine in RELEASE mode.
If in DEBUG mode, and I put break points to find the reason of the crash, then it doesn't crash: It work properly. But if I do not put any break points then it crashes at below code:
Project Background:
My Project includes functionality to read from the device connected at System communication port and transmits data to the MainWindow UI to display. Since to communicate with the communication port we have to use the third party library so I am not using QtSerial Port class which is much simpler and easy to use.
Code Design:
Class MainClass : In this class we have created some forms to display the data read from the device.
Class TestClass: This class will handle all the communication with the device connected at the system Serial Port and use the third party library. This class also have the while loop to read data from the device connected at Serial Port.
Since Test Class is using while loop. So we decided to make a Test Class run in different Thread.
Code for creating Thread in MainClass Constructor:
MainClass::MainClass (QWidget *parent) : QDialog(parent),
ui(new Ui::Analzyer)
{
............................
............................
workerThread = new QThread;
testClassObject = new TestClass(); // Declared in HeaderFile of MainClass
if((workerThread != NULL) && (testClassObject != NULL))
{
workerThread ->moveToThread(testClassObject );
connect(workerThread , SIGNAL(started()), testClassObject, SLOT(SomeFunc()));
connect(testClassObject, SIGNAL(exit()), workerThread , SLOT(quit()));
connect(testClassObject, SIGNAL(exit()), testClassObject, SLOT(deleteLater()));
connect(workerThread , SIGNAL(finished()), workerThread , SLOT(deleteLater()));
// connectToPort Signal is emitted when User clicks the pushbutton from // Main class UI
connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)));
}
}
Crash Code:
void TestClass::openPort(const QString portName)
{
// Here portName is say : "Appliance Interface v2"
quint32 param2 = getParam2ForPortName(portName);
qint16 portNumber = 0;
QByteArray portNameByteArray = portName.toLatin1();
const char *portNameToOpen = portNameByteArray.data();
// Program crashed when return from this function
if(func1(portNameToOpen , param2, 10 , &portNumber) == true)
{
......................
......................
}
}
Here, I added some qDebug() and found that my code crashes when it returns from or call the func1() which is getting called in slot OpenPort(). Below is the prototype of the func1()
bool func1 (const char portDescription[], uInt32 param2,
uInt16 length, Int16 * portNr);
Since, func1() is the part of the library code. So I can not check the defination of the function func1(). I can assure that there is no problem in func1() Since it is being used in different java based projects and it works.
I did some more debugging on the Project and noticed that when in Run in DEBUG Mode with BreakPoints than in the QT Thread Debug Window I can see my connected Slot but when I do not put any breakPoint than my code crashes and in Qt Thread Debug Window I can not see my connected Slot
So, It looks the problem of connection between the Main Class and the Test Class for openPort Slot.
But I am not able to understand taht when i put breakpoints in operPort() function than I can see my openPort Slot in Qt Thread Debug window but when no breakpoints than openPort Slot is not visible in Qt Thread Debug Window and Program Crashes.
Kindly Suggest,
I can assure that there is no problem in func1() Since it is being used in different java based projects and it works.
Wait, is func1() C++ or Java ?
Also, how can you be sure it works ?
Get the library source, compile it yourself, and debug in it.
And, just to be sure, check values of your variables while debugging, and qDebug() them when not debugging
I apologise for replying on my own post but after lots of dicussion on StackOverflow and google. I was able to solve the Issue.
To Solve the Issue:
I changed the SLOT(openPort) as mentioned below:
Connect(this, SIGNAL(connectToPort(QString)), testClassObject, SLOT(openPort(QString)), Qt::DirectConnection);
That is to use the "Qt:DirectConnection" method. If we don't specify a connection method, the direct method is automatically used for connections between objects on the SAME thread.
Since here we have created a new QThread for TestClass and using a thirdParty library which might not be a thread safe.
So using "Qt::DirectConnection" make the openPort() SlOT to run in MainClass Thread. Basically, it's as if emitting the signal calls the slot method "directly".
I am just starting out with QT. I have read through some tutorials, and I think I have an understanding of signals and slots. I am writing a GUI that has various buttons that change the state of my main program. So for example in a drawing app, you would pick different drawing tools (using various buttons).
What is the best way to go about this? My first thought was to try to connect the clicked signal of the PushButton to some function that sets a current_tool variable. I did some searching and couldn't find a way to connect a QObject signal to a regular function.
This leads me to believe that there is probably a different approach. One where I create a new QObject (my own extension that is) that has various GUI properties. I would then define my slots here for the various buttons.
What is the best way to do this in QT. I am new and do not know of the preferred practice.
Any info would be useful,
thanks
You can define these "normal functions" as slots. Slots are just normal functions that can also be called by signals:
class ToolSelector : public QObject {
Q_OBJECT
public:
Tool *selected;
public slots:
void selectBrush();
void selectPen();
void selectFill();
};
ToolSelector::selectBrush() {
delete selected;
selected = new Brush();
}
ToolSelector::selectPen() {
// ...
}
// ...
toolsel = new ToolSelector();
brushButton = new QPushButton();
connect(brushButton, SIGNAL(clicked()), toolsel, SLOT(selectBrush()));
Inherit from the class that uic generates, creating, say, a MyAppWindow class. Provide extra METHODs in that class, as well as a Document or Drawing object. Connect these methods to the signals you're interested in, and them alter a member variable that contains the drawing state.