Move QToolButton to different layouts by just pressing it? - c++

I have here two different layouts, and one QToolButton. My goal is to transfer that button between the two layouts when I click it. I figured this code would work,
snippet:
void DominionLinux::on_toolButton_clicked(string state)
{
if (state=="Disabled"){
ui->verticalLayout_Enabled->addWidget(ui->toolButton);
state = "Enabled";
}
else if (state=="Enabled"){
ui->verticalLayout_Disabled->addWidget(ui->toolButton);
state = "Disabled";
}
}
By default, state == "Disabled". When I test the UI in QTCreator, the first time I click, it works; the button dissapears from one template, and appears on the other. The second time I click when its on the other template, it doesn't. When compiling, I get this warning:
*QMetaObject::connectSlotsByName: No matching signal for on_toolButton_clicked(string)*
Any ideas why the slot stops working?

Any ideas why the slot stops working?
You are missing the signal declaration at the place of the connect as the warning also hints. Also, it seems that you are passing either the slot as the signal to the connect method. A signal should not have the same name as a slot in a Qt application.
Other than that, you may wanna reconsider your design about disabling and enabling a button. Putting them into separate layers is not the appropriate way of doing it.
Moreover, you should probably avoid raw strings for representing states in general. It is better to use enumerations, or boolean for "toggle states".

Related

Qt5: Tell QPlainTextEdit to ignore syntax highlighting changes

I have a QPlainTextEdit widget in my application which has a QSyntaxHighlighter assigned to it. Upon each content change within that text edit area, I need to get a notification (to update the global application save/changed state). However, the signal textChanged() also gets emitted each time the highlighter gets to work, which I need to filter out somehow.
I already had a look at modificationChanged(), but that doesn't seem to work either. It ignores the highlighting changes and successfully notifies me upon the first content change, but not of any subsequent changes. The documentation mentions, that I should be able to reset the internal state with setModified(false) but that method doesn't seem to exist.
Any ideas on how to filter the changes?
Do I have to switch to QTextDocument which seems to have a single contentsChanged() that is said to ignore syntax highlighting changes?
It turns out I already was on the right track...just not all the way:
I indeed need to listen to modificationChanged signals since they are emitted on content changes (which are the relevant events for my application save state handling).
I however originally did not see a way to reset the internal modification state (e.g. when my application saves its state). The reason was that setModified(bool) does not exist for the QPlainTextEdit, but I realized that each of those objects has a QTextDocument internally which does have that method. So I simply call that each time I need to reset the state to non-modified:
m_pPlainTextEdit->document()->setModified(false);
As a result, when the content is changed the next time, modificationChanged will get emitted again so that I can react to it and for example enable the "Save" icon.
BTW: The signal contentsChanged from QTextDocument is also emitted upon formatting changes, so not helpful in my scenario.
I have not tested it, it is just basically an idea.
When the user modifies the text, it is a QKeyEvent.
When the highlighter does, it is some sort of QInputMethodEvent (?)
What you could do is, check if the event is a QKeyEvent, and if it is not, block it.
You can create a filterobject class, or just define the following method in the class that contains the QTextEdit.
bool MyClass::eventFilter(QObject *o, QEvent *e)
{
if (e->type() == QKeyEvent) //The user modified the text edit
return false;
else
return true;
}
And you have to install it (for example in the constructor), if you defined it in the class that contains QTextEdit:
myTextEdit->installEventFilter(this);
Instead of hooking into modificationChanged(), and resetting the modified flag everytime, you could just hook into textChanged(). It's triggered anytime you make a change to the document, regardless if had been previously changed or not...

How to know if the Gtk::ComboBoxText is popup

I am writing a simple GUI, in which I have a ComboBoxText. I write a log message when ever the user clicks on the ComboBoxText.
I have tried almost all the button release and popup signals but no results. The only thing which works is signal_changed() but I don't not need that. Please help me, below is my sample code :
myCombo->signal_button_release_event().connect(sigc::mem_fun(this,&ComboBoxText::ComboInput),false);
and here is the call back function:
bool ComboBoxText::ComboInput(GdkEventButton *pEvt) {
// Here do the desired stuffs !!
return false; }
Use GTK+ property popup-shown. Not sure about Gtkmm syntax, probably property_popup_shown().get_value().
If you need a signal to listen to, connect to popdown or notify::popup-shown (the latter is invoked when property value changes; again, I'm not sure about Gtkmm syntax).
The idea here was to fire an event when the ComboBoxText is clicked. After some readings I figured it out that the ComboBoxText does not fire any on_click event as such.
One could mask a key press event (which by the way gets fired) and call the signal handler. This might not be handy for people who specifically looking for a on_click event but for those who are working with a keyboard or touch screen device. Here is a small chunk of code :`
mCombo.add_events(Gdk::KEY_PRESS_MASK);
mCombo.signal_event().connect(sigc::mem_fun(this,&ClassName::Handler),false);
cheers :)

Changing QLineEdit TextBox's inside of loop dynamically

I'm building some code where I'm running a while loop and, within the loop, am trying to change the contents of a couple of textboxes with QLineEdit's setText(). However, merely calling setText within the loop does not work; the textboxes only change their actual value once the code has run through, instead of at each iteration.
I have little experience with C++ or Qt, but the project I'm working on must use them. Any help?
EDIT: I'm guessing this must be something simple that I simply am having troubles because of my lack of familiarity/knowledge, but if more information is needed I'll gladly provide it!
The problem is that QT needs control to return to the UI thread's event loop in order to update the QLineEdit's visual appearance. The quick and dirty way to run the event loop is to add QCoreApplication::processEvents() after each call to setText(). The proper way to fix it is to move the blocking process that sets the value of the text box into another thread, expose an updateText(QString text) signal, connect it to the TextBox's setText(const QString & text) slot and emit that signal whenever you want the text to be updated.
Please see my answer to a similar question for more detail: unexplained delay after QProgressBar finish loading
You might also want to check out some of the documentation on QThreads and the Qt signal slot system: http://harmattan-dev.nokia.com/docs/library/html/qt4/threads-qobject.html
In my case, calling only repaint() or processEvents() won't do the job.
Within your function loop, call both QCoreApplication::processEvents(); and repaint();:
for (i;...)
{
//do your calculations
//...
QCoreApplication::processEvents();
repaint();
}
Calling ui->mywidget->update() didn't make any different as well.
(Tested for Qt4.8.3 on Kubuntu 12.10 and Qt5.0.1 on Windows XP)

Qt Designer, missing "go to slot" in context menu?

I've been watching a Qt tutorial series on YouTube, in which the author shows how to call a function, when a button is pressed. He right-clicked on the button in Qt Creator IDE and chose "Go to slot", from where he chose the signal which would fire the generated function. Since I am used to develop with Netbeans, I simply tried to follow his example using the embedded Qt Designer. Unfortunately, there is no "Go to slot..." entry when I right-click on my button or any widget. I could, of course, create a new slot for my main window and then connect the button's signal to it, but doing it with a single function just seems way more convenient and clean to me. Is there a way to fix is, or if not, at least a way to do with via code entirely, without having to add a new slot to the main window for every single button that servers a different purpose? Thanks for your help.
While I don't know why the QtDesigner in Netbeans doesn't provide this feature, I know what the feature does: It just creates a slot with a special name in your widget class. Note that it does not add a connect statement. It uses the automatic connection feature, which works like this:
For each slot which name matches this pattern:
void on_X_Y(...)
it will be connected to the signal named Y of the object named X. So if you have a QPushButton named button, and you want to handle the signal pressed, simply create a slot with the following signature:
void on_button_pressed()
If you wonder how this slot gets connected to the signal: This happens in the ui_...h file at the end of setupUi():
QMetaObject::connectSlotsByName(WidgetName);

QTreeWidget; Disabling ui Features when multiple Items are selected in QTree

I'm a student programmer and I am using Qt to build a GUI for work and I have ran into an issue of sorts. In my main interface I have a QTreeWidget that holds data. Also in this GUI I have the buttons Edit, copy, and delete which are already perspectively connected to functions. I would like the edit button to be disabled when multiple items are selected. Here is where I am having my issue. I assume that the best way to do this (once again I am a student) would be some type of connect statement but I have been looking through the Qt Documentation for this widget and cant find anything that seems right for this. I was hoping someone more experienced to be able to provide some direction with this.
I was wondering if I should/can use
void QTreeWidget::itemSelectionChanged () [signal]
If I could use this signal please shed some light because I'm hitting a blank here as I wouldn't know where to begin to relate it to multiple items being selected.
Yea this is the right signal. For example here is trivial implementation of the slot for your question:
void disableItems() {
QList<QTreeWidgetItem*> selection = treeWidget->selectedItems();
if(selection.size() > 1) {
//disable the gui items here
} else {
//maybe reenable items otherwise
}
}
I don't think you can do it solely in QtDesigner, if that's what you're trying to do.
You could define you own slot to handle itemSelectionChanged signal. In that slot you can use selectedItems method of QTreeWidget to check the number of selected items and enable/disable buttons based on that.