I'm using qt creator to create a gui for an vtk aplication.
I've made a #define action and I want to assign that command to a QPushButton.
How do I make the button reproduce my define if pressed?
example.
ui->pushButton->...
The easy way is to define a default reponse slot for your button. In your class definition (the same class that defines the pushButton) you can just create a default slot under the slots section.
class MyMainApplication : public QMainWindow
{
Q_OBJECT
public:
MyMainApplication(QWidget *parent = 0);
~MyMainApplication();
// More stuff in the public section (...)
public slots:
void on_pushButton_clicked(); // This is the important line
// The remaining definitions in your class
};
Now you just program the on_pushButton_clicked() function in your class implementation and it will respond to the click on the button called pushButton.
The syntax for default slots is on_NAMEOFTHEWIDGET_NAMEOFTHESIGNAL.
With the default slots, the connection is made automatically. If you want to use a generic name for the slot you must make the connection manually. For instance, say that instead of
on_pushButton_clicked() you want to use mySlot(). In the class definition you would type
(...)
public slots:
void mySlot();
(...)
and in the class implementation, probably in the constructor, after the ui->setupUi(this); command you would make the connection of the button and your slot:
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(mySlot()));
A final remark: in this particular case, I am almost sure that the slots can also be private.
You need to use Qt's feature called Signals and Slots. Many objects can send signals when interacted with. Example is "clicked()" signal emitted from a QPushButton, or "triggered()" which is emitted upon clicking on QAction.
Main idea is to connect a signal to a slot. Slots are functions which are called when a signal is emitted. I can provide you with a PyQt example:
QtCore.QObject.connect(self.ui.myButton, QtCore.SIGNAL("clicked()"), self.someFunction)
C++ code shouldn't be much different. Check the Qt examples, they provide lots of good stuff.
Related
In my project, I want to call a variable QImage image generated in the mainwindow.h, in other class files, e.g., called SegSetupDialog.h. Here the image is loaded by clicking a pushbutton in mainwindow.ui, and the SegSetupDialog is a QDialog, which pops up by clicking one pushbutton in mainwindow.ui.
I tried to use a signal-slot connection to send qimage of mainwindow to SegSetupDialog as follows.
For Class MainWindow:
SegSetupDialog *segsetup;
if(image.isNull()==false)
{
emit sendImgData(image);
qDebug()<<"sendImgData emitted!";
if(segsetup==NULL) segsetup = new SegSetupDialog();
connect(this, SIGNAL(sendImgData(QImage)),segsetup,SLOT(getImgData(QImage)),Qt::QueuedConnection);
}
In SegSetupDialog::getImgData
void SegSetupDialog::getImgData(QImage qimage)
{
qImg = qimage;
qDebug()<<"qimage received!";
}
The above connection seems not to work since the qDebug message in getImgData is not printed out. Anyone can help check something wrong with codes, or suggest other methods for accessing image of mainwindow? Thanks!!
You need to do the signal/slot connection before you emit the signal. Connections are done once, usually in the constructor.
However, you should probably do the connect() in the constructor of SegSetupDialog instead of the MainWindow one. It's SegSetupDialog that wants to be notified about image data updates, so you should establish the connection there.
Also, to make sure the signals and slots are specified correctly, don't use Qt 4 connect() calls. Use Qt 5 ones that are checked at compile-time:
connect(this, &MainWindow::sendImgData,
segsetup, &SegSetupDialog::getImgData, Qt::QueuedConnection);
(Of course change it appropriately if you move it to the SegSetupDialog constructor.)
I have copied several buttons in design form. As result all buttons got the same slot for clicked(). How to create and assign new personal slots for buttons?
UPD
Trying to use Signals & Slots editor. It was empty in the beginning, and I added new one:
But if I right click on button btnInfoCB->go to slot.. clicked() , it will point me to the same old method.
Qt creator will create slots for you. From designer, Right click on any push button and select 'Go to slots' option. select Clicked() signal press OK. Qt creator will navigate you to the created slot. Qt automatically connects your button clicked signal to the created slots.
You can do the same for all push buttons you created
Qt has an auto-connect feature that connects the slots named like this: on_UIELEMENTNAME_SIGNALNAME(SIGNAL_PARAMS) with the corresponding signal of the ui element, see the documentation here
So to fix this you have 2 options:
Option 1: rename the slots to have all the names corresponding with the names from .ui file:
private slots:
void on_MyFirstBtn_clicked();
void on_MySecondBtn_clicked();
//and so on
Or use option 2: manually connect
private slots:
//notice the prefix "on_" and the suffix "_clicked()" not part of the function name
void MyFirstBtnClicked();
void MySecondBtnClicked();
And in the constructor of the class (i named it MyWidget) add the connect calls:
connect(ui->MyFirstBtn, &QPushButton::clicked, this, &MyWidget::MyFirstBtnClicked);
connect(ui->MySecondBtn, &QPushButton::clicked, this, &MyWidget::MySecondBtnClicked);
LE: I don't recommend using the UI Designer for connecting slots that are defined in code because of maintainability reasons. That feature in Designer is very good if you need to connect already defined signals and slots, like check/unched to show/hide and other similar predefined functionality, but for your defined slots i don't like it.
New slot for an existing QPushButton /w auto connection
You have to change the objectName of QPushButton first. Then right click and create a new slot connection e. g. clicked(). Qt Creator will then create a new slot with the new objectName e. g. void on_newObjectName_clicked() { }. The old slot is no longer used then and you will get a new fresh function.
Manually connect /w signals and slots editor
If you like to connect it through your editor, you first have to click at the QWidget (e. g. MainWindow) and select change signals/slots from the menu. There you have to add a new function e. g. myNewSlot(), which is then available in the drop-down in the signals and slots editor as shown in your screenshot. If you use this type of connection you need to declare the slot in your .h in private slots and in the .cpp file. The object name may still link to an auto connection, so you probably need to change the objectName as well or remove the auto connected slot.
I created a qt class only to make gui and displayed the data on gui.
i didn't want to freeze the gui that's why i created another non_qt class to perform the operation so i made a object in the gui class of non_qt class and pass the parameter in that and started it in a new thread.
now after completing the operation i want to notify the gui class so it can display the results.
i also want to access the status bar of gui class so when non_qt class is performing the operation it can display some message on gui..
(i tried it with qt class but it didn't work that's why i created non_qt class..with non_qt class threading part is working fine but signal part is not working so i'm not able to notify the gui class).
so please help me out how to send signal to a qt class from a not qt class????
The signal is a concept that only applies to classes that derive from QObject.
If you want to trigger a slot, you don't need a signal. If the receiving object lives in the same thread (and only then), you can call the slot method on the reciving object directly.
For example, given an instance of a GUI object with a slot:
MainWindow * mainWindow;
class MainWindow : public QWidget {
Q_OBJECT
...
Q_SLOT void setStatus(const QString &);
...
};
You can simply do:
// The assert is essential to prevent bad bugs. If it triggers,
// you must use `QMetaObject::invokeMethod` instead.
Q_ASSERT(mainWindow->thread() == QThread::currentThread());
mainWindow->setStatus("Finished");
If the receiving object may live in another thread, or if you don't want to worry about threading issues, then you must use QMetaObject::invokeMethod, as follows:
// This is always safe. No need for asserts.
QMetaObject::invokeMethod(mainWindow, "setStatus",
Q_ARG(QString, "Finished"));
This overload of invokeMethod will correctly choose the connection type depending on whether the receiving object runs in the same thread. If the receiver is in the same thread, the call is a direct call. If it runs in another thread, the call will be converted to a QMetaCallEvent and posted to the receving object. This is thread-safe and doesn't require the receving object's setStatus method to be thread-safe.
I'm trying to enable a QPushButton after another QPushButton is clicked and I've run into a problem. The first QPushButton can emit a clicked() signal while the second QPushButton only has slots of the form setEnabled(bool) and setDisabled(bool).
Basically, I'm trying to do
connect(ui->pbViewVolume, SIGNAL(clicked()),
ui->pbSaveAsImage, SLOT(setEnabled(true)));
Since it's not possible to send a signal with fewer parameters than the slot, how can I best do this? The only way I see is to create a public slot for my MainWindow like
void EnableSaveAsImageButton(){
ui->pbSaveAsImage->setEnabled(true);
}
but I'd rather not fill my MainWindow with this sort of rubbish function.
You have to create that slot.
You don't need to make that slot public, make it private.
This function is not rubbish.
I've read lots of similar threads to this one but im not such a great programmer that i can make sense of it all. Im using qtcreator to make life simple and want to maka a program that can trigger another process, monitor its stdout and then kill it if necessary.
What I assume i want to do is create a QTextedit in the designer and plug a signal into it that updates the contained text whenever the stream updates, so far so good, but thats where i get fuzzy. My initial thought was to create a subclass of QObject that starts the process as a QProcess and whenever the stdout updates the QObject and appends new data to the QTextedit box.
So my program structure would run like this:
on button press create new QObject derived class.
The QObject derived class constructor starts a QProcess and connects the readyReadStdout() signal to the derived qObject class slot.
When the derived QObject is triggered it takes readyReadStdout() and appends any new data to the QTetEdit box.
on button press, call the derived QObject destructor and which kills the process.
Has anybody done something similar? Like i say ive read similar posts but sometimes it takes asking a question in your own words to be able to understand it
Thanks everyone (also my forst post, woo:)
Ok so heres my update:
I have added an instance of QProcess class (named proc) to my mainWindow class and also new instance of a QObject derived class (named procLog) to which I added a slot. I want this slot to take the readyReadStandardOutput() signal as a trigger to call readAllStandardOutput() and emit the new line to a new signal in procLog, I'm having trouble connecting the QProcess slot to the QObject derived class. heres what I'm trying:
connect(proc, SIGNAL(readyReadStandardOutput ()), procLog, SLOT(logReady()));
I get, error: QObject::connect: Cannot connect (null)::readyReadStandardOutput () to (null)::logReady()
Do you know why this is. Aslo is there a way to add code blocks to text in the comments?
thanks!