Qt - Remembering the last checked Radiobutton - c++

I have 3 radio buttons and a spinbox. Each radio button is supposed to chnage the spinboxes value to inches, feet or meters respectively. How would i do that? I would have to know which radio button was active last, right? Could someone give me some example code please?

Radio Button and check boxes hold their state as value, and expose it to your user. You can call isChecked() to know the state of your member variable radio button. Something like
void some_button_hit(bool checked)
{
if (inches.isChecked()) {...}
else if (feet.isChecked()) {...}
else if (meters.isChecked()) {...}
}
and 'wire' the event toggled from any of these. This is usually done in initialization,
using the form editor, or via connect.
Using the form editor, right click on a radio button, and follow goto slot...
The editor build and connect the event handler:
void GroupBox::on_feet_toggled(bool checked)
{
ui->label->setText("feet");
}
void GroupBox::on_inches_toggled(bool checked)
{
ui->label->setText("inches");
}
void GroupBox::on_meters_toggled(bool checked)
{
ui->label->setText("meters");
}

Related

Do I need to check one by one to know which radiobutton is checked in a group in Qt

I know that I can use this kind of code to know which radio button is checked in Qt:
int checkButton;
if( ui->radioButton_0->isChecked() ){
checkButton = 0;
}else if(ui->radioButton_1->isChecked()){
checkButton = 1;
}else if
...
Are there any easier way to know which radio button is checked in a group in Qt. I think it is really helpful if there is such kind of easier way when the group of radio button is large. Code may look like that:
int checkbutton = groupName.getCheckButtonIngroup();
Also we can put a few radiobuttons in groupbox in Qt Designer and after this find children of groupbox, add children to buttonGroup and use the checkedId or checkedButton methods.
void MainWindow::on_pushButton_15_clicked()
{
QButtonGroup group;
QList<QRadioButton *> allButtons = ui->groupBox->findChildren<QRadioButton *>();
qDebug() <<allButtons.size();
for(int i = 0; i < allButtons.size(); ++i)
{
group.addButton(allButtons[i],i);
}
qDebug() << group.checkedId();
qDebug() << group.checkedButton();
}
First of all you need to add all radio buttons to a button group. There are two ways to do that:
In Qt Designer select all radio buttons you want to add and select Assign to button group from the context menu.
From the code. Create a new QButtonGroup and add the buttons there with QButtonGroup::addButton.
Then anytime you can get to know what button is checked:
If you need a pointer of a checked button use QButtonGroup::checkedButton.
If you need a number of the button you need to add buttons to the group manually with addButton(QAbstractButton* button, int id). After this use QButtonGroup::checkedId to get an identifier of the checked button.

wxTaskBar with radioitems

I'm trying to implement a language choice submenu (radioitems) in the system tray menu using wxWidgets 2.8.12. But when I try to check the active language the item is still unchecked. Here is a piece of code from TrayIcon::CreatePopUpMenu()
info = locale->FindLanguageInfo(languages[i]); // languages - array of strings
wxMenuItem *item = menuLanguage->AppendRadioItem(ID_Locale + info->Language, info->Description);
if (locale->GetLanguage() == (item->GetId() - ID_Locale)))
item->Check(true);
Events:
BEGIN_EVENT_TABLE(SystemTrayIcon, wxTaskBarIcon)
EVT_MENU_RANGE(ID_Locale, ID_Locale + LANGUAGES_COUNT, TrayIcon::ChangeAppLocale)
EVT_UPDATE_UI_RANGE(ID_Locale, ID_Locale + LANGUAGES_COUNT, TrayIcon::UISelectLocale)
END_EVENT_TABLE()
Action:
void TrayIcon::OnMenuUILocaleChange(wxUpdateUIEvent &event)
{
int id = locale->GetLanguage();
if (id == (event.GetId() - ID_Locale))
{
event.Check(true);
}
}
So when I click on a radioitem the actions defined in TrayIcon::ChangeAppLocale are performed but the button is unchecked when I'm creating the menu. During the debugging I can see that item->Check(true) takes place and item->Checkable() becomes true. But later in the TrayIcon::OnMenuUILocaleChange the item is unchecked (I know it's a bit of doubleworking here but at least I can watch the check value)
When The same actions for the app menu (adding language submenu) are performed the check is active.
I have seen Popup menu radio item checks but the advices from there didn't help. Thank you

How to avoid mouse click on one widget triggering the signals in others in Qt?

In my app I'm using a QTableView to show a list of images and I select some of the images by clicking left mouse button and pressing control keyboard button when I do so the app looks as the below stated image:
But then when I try to use other buttons on the app like "Destination" and then try to select a destination folder then the app looks like this below:
Problem occurs when I click the "select folder" button and try to select the folder. What happens is that click on the folder selection tab, triggers QTableView widget in which I show the image and the deselects all the selected images. I want to avoid it. The way I now track the left mouse button clicks on QTableView widget is as below:
bool MainWindow::eventFilter(QObject* obj, QEvent *ev)
{
if(obj == ui->listOfImages->viewport())
{
QMouseEvent * mouseEv = static_cast<QMouseEvent*>(ev);
if((mouseEv->buttons() & Qt::LeftButton) && (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) == true))
{
controlButtonCounter++;
fetch = true;
return QObject::eventFilter(obj,ev);
}
else if((mouseEv->buttons() & Qt::LeftButton) && (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) == false))
{
if(selectedImages.size()>0)
{
ui->listOfImages->clearSelection();
selectedImages.clear();
}
fetch = false;
controlButtonCounter = 0;
}
}
return QObject::eventFilter(obj,ev);
}
Here ui->listOfImages is the QTableView widget. Other things like controlButtonCounter are irrelevant in taking the mouse clicks, I use it for other purposes.
Please say me how I can avoid triggering QTableView widget when I'm pressing on other things that fall in the same region as the QTableView.
if(obj = ui->listOfImages->viewport())
You are not doing a comparison there, you are assigning a value to the obj variable.
It should be like this:
if(obj == ui->listOfImages->viewport())
I'm not sure but maybe it can help you:
void setWindowModality(Qt::WindowModality windowModality)
This property holds which windows are blocked by the modal widget.
This property only makes sense for windows. A modal widget prevents widgets in other windows from getting input. The value of this property controls which windows are blocked when the widget is visible. Changing this property while the window is visible has no effect; you must hide() the widget first, then show() it again.
By default, this property is Qt::NonModal.

Fail to clear QLineEdit after selecting item from QCompleter

using PopupCompletion mode when you select an item (using arrow keys) and press return - lineEdit should become empty (i clear lineEdit when return is pressed), but lineEdit does not become empty. (If you press 'Enter' again it will empty the lineEdit). So i think pressing return does clear lineEdit, but pressing return also tells QCompleter to insert selected item into lineEdit, so it seems like nothing happens.
But, if you click the item insted of selecting it with arrows - everything works fine.
I tried to find the solution on the internet, but i found only one person that had the same problem: http://lists.trolltech.com/qt-interest/2006-10/thread00985-0.html . Sadly there are no answers. Please read his question because it will help understand my problem.
How can I clean LineEdit after QCompleter inserted selected item? (catching activated signal does not help)
The issue here is that the completer actually contains a pop-up, which is actually a separate QAbstractItemView widget (refer to the QCompleter::popup() documentation). As such, when you press 'Enter' on the QCompleter, the key event actually goes to the pop-up and not the line edit.
There are two different ways to resolve your issue:
Option 1
Connect the completer's activated signal to the line edit's clear slot, but do it as a QueuedConnection:
QObject::connect(completer, SIGNAL(activated(const QString&)),
lineEdit, SLOT(clear()),
Qt::QueuedConnection);
The reason why using a direct connection doesn't work is because your are essentially dependent on the order in which slots get called from a signal. Using a QueuedConnection gets around this. From a code maintenance standpoint, I don't really prefer this solution because it isn't clear what your intention is just by looking at the code.
Option 2
Write an event filter around the pop-up to filter out the 'Enter' key to clear the line edit explicitly. Your event filter would end up looking something like this:
class EventFilter : public QObject
{
Q_OBJECT
public:
EventFilter(QLineEdit* lineEdit, QObject* parent = NULL)
:QObject(parent)
,mLineEdit(lineEdit)
{ }
virtual ~EventFilter()
{ }
bool eventFilter(QObject* watched, QEvent* event)
{
QAbstractItemView* view = qobject_cast<QAbstractItemView*>(watched);
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Return ||
keyEvent->key() == Qt::Key_Enter)
{
mLineEdit->clear();
view->hide();
return true;
}
}
return false;
}
private:
QLineEdit* mLineEdit;
};
You would then install the event filter on the completer's pop-up:
EventFilter* filter = new EventFilter(lineEdit);
completer->popup()->installEventFilter(filter);
This option is more work, but it's clearer as to what you are doing. Moreover, you can perform additional customization this way, if you prefer.

how to use ribbon category to switch view?

I want to use two ribbon category buttons to switch between two different views, but I found it can't add event handler to the button.
Is there any hint to solve this problem? Better if there is some sample, actually I'm new to MFC.
You could try hooking into this event?
AFX_WM_ON_CHANGE_RIBBON_CATEGORY
An option I have found successful was to subclass CMFCRibbonBar and override PreTranslateMessage and check for mouse clicks. Below are the steps I took which have thus far worked well.
Subclass CMFCRibbon - in my example I created CCustomRibbonBar
Override PreTranslateMessage, and add an int value to keep track of the tab
Create a custom windows message that your applications MainForm handles -WM_ACTIVE_RIBBON_TAB_CHANGED in my example
Inside of PreTranslateMessage check for Left Mouse Up event
In the event of a left mouse button up, let the Ribbon finish handling the message and then query the Active Category.
Post the active category to MainForm (or other form)
In your MainForm, handle the category and take into account that with most events the category will not have changed.
Then in my override I check for the mouse up event and retrieve the Active category
Inside Class Declaration
virtual BOOL PreTranslateMessage(MSG* pMsg);
int m_LastActiveCategory;
Inside Class Definition
BOOL CCustomRibbonBar::PreTranslateMessage(MSG* pMsg)
{
//If command was finishing a click
if(pMsg->message == WM_LBUTTONUP && pMsg->wParam == 0)
{
//Allow ribbon to handle itself first
BOOL result = CMFCRibbonBar::PreTranslateMessage(pMsg);
//Get new active tab
int activeTab = GetCategoryIndex(GetActiveCategory());
//If tab has changed, forward message
if(activeTab != m_LastActiveCategory)
{
//forward message to parent
::SendMessage(GetParentFrame()->GetSafeHwnd(),WM_ACTIVE_RIBBON_TAB_CHANGED,activeTab,0);
m_LastActiveCategory = activeTab;
}
return result;
}
//Otherwise handle like normal
return CMFCRibbonBar::PreTranslateMessage(pMsg);
}