I have created a UI that has a listWidget with 10 items and I want to create a signal that that executes a custom slot when I double-click on a specific item of the listWidget (ie. the last one).
The signal/slot I implemented is as follows
QObject::connect(ui->listWidget_RD_commands, SIGNAL(QListWidget::itemDoubleClicked(ui->listWidget_RD_commands->item(9))), this, SLOT(flash_read));
It throws no errors but, in the application output window when I run the code, the following message pops up
When I try to implement the signal/slot with the new way
QObject::connect(ui->listWidget_RD_commands, &QListWidget::itemDoubleClicked(ui->listWidget_RD_commands->item(9)), this, &MainWindow::flash_read);
an error pops up saying
mainwindow.cpp:102:64: error: call to non-static member function without an object argument
So, what am I doing wrong here?
Related
I've inherited a lotus notes application and one of the things that really irks me is every function/sub/property has onerror statements and errorhandler labels that aside from typos all do the exact same thing. Additionally, and unfortunately this application has gone through several revisions and some errorhandler: labels have revisions where as other don't. I'd like to standardize and centralize this behavior.
Is there a way to have a single error handler for a given document, where if an error is raised anywhere in the document, that particular error handler is called?
Thank you,
You can have one error handler per script execution. You cannot have one global to a document. Each event that fires in a document results in a new script execution.
That said, it is generally advantageous to have one error handler per function, but that advantage is lost if they are actually exactly the same. The better practice is to customize them so that each error handler records the name of the current function. (Of course, due to copy/paste laziness, this is frequently more effective in theory than in practice.)
If you have an On Error Goto SomeLabel statement (where SomeLabel is whatever label the code actually uses), the label must exist in the same Sub/Function that contains that statement so, technically, you need a separate handler for each Sub/Function.
However, some things might simplify matters...
If one Sub/Function calls another Sub/Function, and the inner one doesn't have an error handler but the outer one (the caller) does, then an error in the inner Sub/Function will be caught by the handler in the caller.
This setup gives you less information (you can't get the line number on which the error occurred in the inner Sub/Function), but it might be helpful if you have any Subs/Functions that you're sure either can't produce an error, or only have one line on which an error could occur.
If you have some static message-text or logging which is identical in many error handlers, you could have a Sub/Function in the Form Globals (or in a script library to absolutely minimise code duplication) that contains the static parts of the error handlers, and takes arguments for the variable parts (error message, line number, and Sub/Function name).
Finally, this code will produce the name of the current Sub/Function and makes it easier to use the same error handler in many places, as long as the code declarations contain %include "lsconst.lss" or you use a script library containing the same %include statement:
GetThreadInfo(LSI_THREAD_PROC)
Another function, LSI_Info, can also give you the name of the current Sub/Function, but isn't supported by IBM, and should be avoided.
I use SpriteKit for Mac OS X (not iOS) to run my programs.
At the end of the "applicationDidFinishLaunching" method of the "AppDelegate"-Class I start all things which are needed for initialization. Some methods do not like to be called from a background-thread like setting window-titles, resizing windows and some other tasks. So all these things are done in the main-thread.
Then we come to my problem: I cannot simply run my main program at the end of the "applicationDidFinishLaunching" method, because when I do so, the "applicationDidFinishLaunching" method does not quit until my main program quits. And my main program does not quit, because it shows some animation on the screen directly after starting the program.
In the case, that the "applicationDidFinishLaunching" method does not quit, SpriteKit does not redraw the window, so my animation runs but I see a white window.
After quitting my program, the "applicationDidFinishLaunching" method quits, too, and I see the last picture of the animation.
So I realized a workaround: I now do the initialization in the "applicationDidFinishLaunching" method and then start a background thread which runs my main program.
The "applicationDidFinishLaunching" quits after starting the background-thread and the window is updated as expected. Everything runs fine with the background-thread doing the animation.
And now the problem, I cound not solve: I need to hide the menu bar, not directly when starting the program, but after some time.
NSMenu.setMenuBarVisible(false)
Doing so is no problem when calling from the main-thread but if I hide the menu-bar from my background thread, then I can hide it once, make it visible once, hide it a second time and when making it visible a second time an exception in the AppDelegate Class stops my program:
Thread 1: EXC_BAD_ACCESS (code=EXC_i386_GPFLT)
My idea to solve this problem, was to post an event, which is handeled by the main-thread. But if I post a keyboard event for example, the event-handling is done within the background-thread, too.
Events like selecting a menu by the user, not programmatically are handeled from the main thread but I did not find a way to post an event which is then handeled in the main thread instead of the thread, which contains the sendEvent-command:
NSApplication.sharedApplication().sendEvent(event!) // Called from background-thread
Has anybody an idea of sending an event which is handeled by the main-thread
or
Running my program completely in the main-thread without having the problem, that the window-content is not drawn at all. This second solution would be my favourite, because there are some more things, which make problems within a background thread.
Perhaps I can start my main program from another method, some time after "applicationDidFinishLaunching" has finished.
Some deeper information to the topic above but still no solution:
I discovered, that there exists a function "performSelectorOnMainThread" which can be called from swift like this:
NSApplication.performSelectorOnMainThread(Selector(myFunctionToCall()), withObject: nil, waitUntilDone: true)
This call compiles, my function is called but in my background thread not on the main thread and an error is dumped:
2015-01-17 20:11:09.142 AudioDatabase[4449:2099588] +[NSApplication (null selector)]: unrecognized selector sent to class 0x7fff7b1d8be0
But execution continues. I was not able to call the function on any other than a few types like NSApplication, NSObject, NSThread like a class function. But I never reached the main loop with this.
Another idea was to use NSInvocation, but when I look in the documentation, only the Objective-C Part appears.
It would help, if it was possible, to simply call a function of mine with or without arguments that runs in the main thread and can do there something.
While running my program in a background thread, I discovered a way, to execute neccessary commands in the main-thread asynchronous. To do so, you have to call:
dispatch_async(dispatch_get_main_queue())
{
// This block runs in the main thread
}
So my question was, so show and hide the menu bar without crashing my program. Here are the finished functions which work, when called from a background-thread:
func m_MenuBarShow ()
{
dispatch_async(dispatch_get_main_queue())
{
NSMenu.setMenuBarVisible(true) // Class func, must be called on the Class (NSMenu) and not on the Instance (NSApp.sharedApp.mainMenu)
}
}
func m_MenuBarHide ()
{
dispatch_async(dispatch_get_main_queue())
{
NSMenu.setMenuBarVisible(false) // Class func
}
}
Please note that there is a small restriction on using this: The block is called asynchronous, that means you have to make sure, that it is finished, until doing something with the result. In the case of showing the menu bar this is no problem. But if you want to do something like opening a file, you must handle this.
I will explain this as an answer to another question of mine. Please have a look at: Open File Dialog crashes in Swift
I have a table with some data that I want to be able to edit through the QTableWidget. Upon trying to connect the currentItemChanged signal:
self.QTableWidget.currentItemChanged(QTableWidgetItem,QTableWidgetItem).connect(self.editCell)
I get the following error:
'TypeError: native Qt signal is not callable'
I went looking in to the QtDesigner, where you can connect signals. I made a QTableWidget, and connected it to a label so that changing the currentItem hid the label.
In the signal connecting dialog the currentItemChanged signal was written thus:
currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)
I don't know what the * means, but I assume it's important.
Am I using the wrong signal or is my syntax wrong somehow? In short, I want there a signal to be emitted upon changing any particular item/cell(I'm not sure what the distinction is)
____________________EDIT_________________________
EDIT: In the QTableWidgetItem class documentation I also found that it has functions column() and row().
I tried adding them like this:
self.QTableWidget.currentItemChanged(QTableWidgetItem.column(QTableWidgetItem.column()),QTableWidgetItem.row()).connect(self.editCell)
But got the error:
TypeError: descriptor 'column' requires a 'PySide.QtGui.QTableWidgetItem' object but received a 'Shiboken.ObjectType
This bit is concerning:
self.QTableWidget
If your table is literally called "QTableWidget" there may be confusion later on. Specifically, the error you are getting makes it look like you are calling QTableWidget.currentItemChanged.
Also, its worth reviewing the PyQT documentation on "new-style signals", specifically on dealing with overloads to understand how it all works. Fortunately however, QTableWidget.currentItemChanged isn't overloaded so, the code you should be using should just be:
self.yourTable.currentItemChanged.connect(self.editCell)
Regarding your later edits, in this code:
currentItemChanged(QTableWidgetItem*,QTableWidgetItem*)
The QTableWidgetItems that are being parsed are arguments that are given to the signal. You can't change them, as they are definined in the method that defines the slot, and passed when the signal is fired. From the documentation linked above:
void currentItemChanged (QTableWidgetItem *,QTableWidgetItem *)
This signal is emitted whenever the current item changes. The previous item is the item that previously had the focus, current is the new current item.
I'm standing in front of a small (maybe not) problem. I have one function which parses XML file (very big xml ~1Gb) so it takes many time (5-6 mins to finish the func). I don't want to use it in GUI-thread because of known issues (mainwindow freezes and nothing happened, so user thinks everything goes wrong). I've tried to solve this problem by using
QtConcurrent::run
But one more problem appeared: if user press X (close button in top right corner) main GUI-thread goes down, but child-thread which was generated my QtConcurrent::run continue his work and I can kill him only by task manager.
I've decided to use QThread instead of QtConcurrent::run6 but I don't understand how can I run MainWindow class function:
void MainWindow::parseXML()
I've tried to create smth like this:
class pThread : public QThread
{
Q_OBJECT
private:
void run();
};
void pThread::run(){
MainWindow::parseXML();
}
But when I'm trying to compile it error appears:
cannot call member function 'void MainWindow::parseXML()' without object
Moreover, I don't know if it possible to update GUI-thread through this method (parseXML function changes statusBar)
What should I do?
The recommended ways to work with threads in Qt is not to inherit from QThread class, see the documentation here and you should be able to do it after that.
And yes it is possible to update the mainwindow from the thread, just code the signals and slots for that functionality, into mainwindow class code a slot that updates the progress and into the class that does the work (the xml parsing you need - there is no reason that functionality should be into the mainwindow class anyway) you code the signal that emit the progress and connect it with mainwindow's slot with Qt::QueuedConnection (note that the default auto-connection will become queued if the objects are in separate threads).
Another option is to use start a QRunnable with QThreadPool. you may want to check documentation. Be ware to wait the spawned threads with QThreadPool::waitForDone().
I am developing a Windows forms application which connects to a piece of hardware, acquires a lot of data (~1 GSample/sec), processes it, and spits it out to the screen upon a button click. I am now trying to automate the process in a loop that can be started/stopped at any time so I can monitor it whilst tweaking the input to the acquisition hardware. I thinks it's clear that I need to do this on a separate thread, but I'm having a heck of a time trying to do this in c++/cli - I have found a number of good examples using MFC, which is not supported by Express.
Specifically: My task is to press a button which is handled in Form1.h, to call a function in my main file Acquisition.cpp which contains the following code (currently an infinite loop)
void Form1::realTimeUpdate()
{
// live is a boolean variable set by a button on the form
while(live)
{
displayVariance(getVar(getQuadratures(100),nbrSamples));
}
}
I wish to execute this code in a separate thread so that the main program can listen for the user request to stop the operation. Without threading, I currently have to forcefully quit the program (or set it to run a fixed number of times) to stop it.
Is there any suggestions how I might go about running this code on a separate thread?
I've (unsuccessfully) tried a few things already:
Modifying the example given in This Microsoft Example. Problem: requires /clr:oldSyntax option which is incompatible with the other 1300 lines of code in the program.
Trying to do what I'd do in Java (Declare a global thread and start/stop it from any point in the code. Problem: Compiler won't let me declare a global System::Threading.Thread
this beautiful example. Problem: Requires MFC.
Any suggestions would be greatly appreciated!
You can use a BackgroundWorker or a Thread to handle this. You'll need to make sure that the portion of your work that updates the UI is marshaled back to the UI thread, however.
Here is a tutorial on threading in C++/CLI.
For the record, upon Reed's suggestion about using a BackgroundWorker, I sifted through the code at the bottom of this page and modified my code so that:
It created a new backgroundWorker BGWorker in which BGWorker->DoWork() called my realTimeUpdate() function.
A button on the main Form calls either RunWorkerAsync() or CancelAsync() depending on whether or not the process is running (checked by a boolean flag in my main program).
The realTimeUpdate() function is now passed a BackgroundWorker - realTimeUpdate(BackgroundWorker^ worker, DoWorkEventArgs ^ e) After each calculation is complete within the internal loop, it calls worker->ReportProgress(result) function. In the BGWorker->ProgressChanged() function a separate function, upDataUI(int) draws the result on the main form.
Thanks again for the help.