Single function that handle multiple QObjects - qt

Hi I have a problem, in my program I have several QLabel and QTextbrowser, at times, I want each of them to display something, but I want to do this through another function called NewMessage. So NewMessage will receive message from QLabel or QTextbrowser, and process them, then display it. But the problem is I don't want to have overloading function for QLabel and QTextBrowser, I want only 1 NewMessage function that can handle message pass in by either QLabel or QTextBrowser(the objects have to pass themselves in as well), how should I do that? Does it has to do with something called casting? Thank you !

I'm not sure I fully understand what you want to achieve. May be you could start by reading Qt documentation about QObject and qobject_cast :
http://doc.qt.io/qt-5/qobject.html#qobject_cast

Related

How to automatically update a QLineEdit with the value of another variable

I've got an std::string object called str;
I've also got an QLineEdit object called line_edit.
I need that str reflects whatever the user writes in line_edit, this I know how to do trough signals and slots.
But I also need that whenever str changes , QLineEdit automatically displays the new contents of str.
How can I do this?
Is it MVC what I need? I've been reading about it but I can't get it yet.
Also, examples I've read try to keep mutually updated subobjects of QWidget
which makes me think there is some magic happening in there.
How can I achieve that reactivity?
First of all it might be easier to use QString instead of std::string.
You can call line_edit->setText(str); to update line_edit from your code.
You can use the signal QLineEdit::textChanged to modify the content of str when writing to the QLineEdit.
There are multiple ways of handling signals, one way would be to use QObject::connect
It might look like this: QObject::connect(line_edit, &QLineEdit::textChanged, this, &YourClassName::setText);
And then you create setText(){ str = line_edit->text}

How to avoid segfault after calling deleteLater on pointer?

I have a GraphicsScene:public QGraphicsScene inherited class with a single QGraphicsView looking at it and QTimer, ticking to call function
void GraphicsScene::adv()
{
if (actor)
views().at(0)->ensureVisible(actor,200,100);
advance();
}
advance() is an overriden method which is send to all QGraphicsItem objects on scene. The point of this function - I want to make sure actor is always visible.
actor is a unit:public QGraphicsPixmapItem object on GraphicsScene.
At some point in actor method I call deleteLater().
The next timer tick I receive SEGFAULT at views().at(0)->ensureVisible(actor,200,100); line
I wonder, why if (actor) passes as true after deleteLater() and what is the correct condition should I use?
I have an object being asynchronically deleted by deleteLater()
and wonder if there is a way to prevent accessing it from other
objects?
Yes, there is a way to tell programmatically whether or not the object was already deleted by using QPointer<MyQObject> as described. But that way is somewhat slow and your application code should rather have better logic to avoid that. Like, before calling deleteLater your code removes the reference for that object from, say, views() and your code should check for the view still there.
If you call deleteLater() from inside your actor, the container GraphicsScene still has its pointer on it - the object itself doesn't reset all external pointers to it.
You have to reset this pointer - the member actor of your GraphicsScene to get your if-statement in adv() working.

Can I pass an argument to the slot function when using QObject::connect?

Qt4.8.5
QObject::connect(button,SIGNAL(clicked()),label,SLOT(setText("dd"));
The Qt Creator tell me It's wrong . What's the problem ?
That you can't pass arguments in a connect() statement. You need a "trampoline" slot that sets the text of your label (or, in Qt 5, you might choose to use a lambda).
For instance, by using a subclass:
class MyLabel : public QLabel {
Q_OBJECT
public slots:
void setTextToFoo() { setText("foo"); }
};
// ...
connect(button,SIGNAL(clicked()),label,SLOT(setTextToFoo());
It depends what exactly you are trying to achieve, to be honest, the example code you provided is not very functional, is "dd" a particular static value you are using, or potentially some other string? Where does it come from, is it in the scope of the called, or is it sent by the caller, which is the usual practice when sending arguments to slots.
Either way, in order to make a connect statement the first requirement is for the arguments to match, clicked() has no arguments while setText() has one, so there is a mismatch. As of how to resolve that mismatch, the easiest way is to use simple wrappers, although you can use a QSignalMapper and as of Qt5, lambdas and std::bind.
For starters, you cannot specify the actual argument instance in the connect statement, even with arguments on both sides you only need to specify the types to help resolve overloads (it is terrible with the new connection syntax in Qt5), and not any actual identifiers or literals.
In case of the more usual scenario, where the data is send to the slot by the caller, the identifier or literal is specified in the emit signal(value) statement. Since you don't have clicked(const QString &) you need a wrapper slot that you connect to clicked() and emit with the value in that wrapper slot, or subclass the button and add your own overload of clicked(QString).
In case the value is in the scope of the called, then subclassing doesn't make much sense, all you need is the wrapper slot in the scope of the called object.
If you want more, you will have to use Qt 5, whose syntax is significantly more powerful.
If the question is whats wrong, just remember the parameter number must be the same for the Signal and the Slot. Asking a collegue and according the Peppe, setText(QString) wait for One parameter and the Clicked() is empty...A custom slot is to call the setText() method indirectly.
You can look that : http://qt-project.org/doc/qt-4.8/widgets-calculator.html
It uses the QWidget, an important part of Qt interfaces beside QML.

Qt SLOTS parameters (Beginner)

I'm a beginner to Qt and am making (or at least trying to make) a basic calculator. If I understand correctly, when doing this:
connect(my_button_4, SIGNAL(clicked()), this, SLOT(writeNumberLbl("4")));
The "4" is not accessible (rather, only its type is) in writeNumberLbl. Basically, I would like so that when the button is clicked, the label sets its text to "4". However, I have the numbers 0 to 9, so I wanted to do:
connect(my_button_0, SIGNAL(clicked()), this, SLOT(writeNumberLbl("0")));
connect(my_button_1, SIGNAL(clicked()), this, SLOT(writeNumberLbl("1")));
...
connect(my_button_9, SIGNAL(clicked()), this, SLOT(writeNumberLbl("9")));
My writeNumberLbl function is:
void Calculator::preWriteVal(QChar val)
{
QString curVal = ui.lbl_output->text();
curVal += val;
ui.lbl_output->setText(curVal);
}
However, I can see that this will not work due to the parameter, 'val'. Could someone please point me in the right direction? Thank you. I did look to see if this question had already been answered and couldn't find anything. If it has, please provide me a link.
Also, is it possible, using Qt Designer 4, to connect a widget to a custom slot?
Thank you.
As far as I know,Qt's signal/slot system requires that the number of parameters of signal function is not less than that of slots function.
In your example,the signal function click() have zero parameters and slot function writeNumberLbl("4") have one parameter,this will not be accepted by the Qt's signal/slot system and if you run your program in debug mode of Qt creator,the qDebug will show you a message like 'Incompatiable signal/slot' blalbalba~. To solve this problem, just read the article given by Arnold Spence. It is quite clear.
There are a number of ways to tackle this problem and they are outlined very nicely here. Although that page is a bit old, I think it is still quite valid. I would recommend using a signal mapper.
For your second question, yes. You can connect signals and slots using Qt Designer by setting the designer in "Edit Signals/Slots" mode. Once in this mode, for example, you can drag a connection line from a button to the form. A dialog will open up allowing you to choose the signal and slot to connect. If you haven't already implemented a slot in code, you can specify the name of a slot and then add the code for it afterward.
The number of parameters in Slot can not exit those in Signal? and pressed() has none. You have two choices (three, counting the dumb one):
Use QSignalMapper. Its help is self-explanatory.
Connect all your buttons to single slot. In it, find out what button has been pressed. QObject::sender() function helps.
There are even more ways, but more complicated.

nube: stdio to QTextedit

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!

Resources