I have a Qt window which contains a QComboBox and a few QLabels and QLineEdits. Based on the QComboBox value that the user chooses, I would like to dynamically change the QLabels and QLineEdits in the window while it is still open.
For example, if the QComboBox has a list of countries, and the user chooses France, I would like to change all the QLabels and QLineEdits into French; the user is then expected to fill out the QLineEdits in French before clicking on the Save/Close button at the bottom.
Can this be done in Qt?
If you are only looking for language translating, there are other ways to do that in Qt where you can use dictionaries to translate Ui text. Take a look at https://doc.qt.io/qt-5/qtlinguist-hellotr-example.html
But it sounds like your question is not meant to be only about language, so to do this you can use the QComboBox signal currentTextChanged, and a slot that will receive the current value and update labels based on that text. Alternately if you do not want to use a bunch of ifs you could use the signal currentIndexChanged and use a switch.
In my ui file I have (4) objects: a comboBox and label1 through 3.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->comboBox->addItem("Selected Option 1");
ui->comboBox->addItem("Selected Option 2");
ui->comboBox->addItem("Selected Option 3");
connect(ui->comboBox, &QComboBox::currentTextChanged,
this, &MainWindow::setLabelText);
}
void MainWindow::setLabelText(const QString comboText)
{
if(comboText == "Selected Option 1")
{
ui->label1->setText("Text when option 1 is selected");
ui->label2->setText("Text when option 1 is selected");
ui->label3->setText("Text when option 1 is selected");
}
else if(comboText == "Selected Option 2")
{
ui->label1->setText("Text when option 2 is selected");
ui->label2->setText("Text when option 2 is selected");
ui->label3->setText("Text when option 2 is selected");
}
else if(comboText == "Selected Option 3")
{
ui->label1->setText("Text when option 3 is selected");
ui->label2->setText("Text when option 3 is selected");
ui->label3->setText("Text when option 3 is selected");
}
}
In your header make sure you define setLabeText as a slot.
private slots:
void setLabelText(const QString comboText);
Related
I have an editable QComboBox. I add some items to it with associated user data.
QComboBox *myCB = new QComboBox;
myCB->setEditable(true);
myCB->addItem("Item1", "1");
myCB->addItem("Item2", "2");
myCB->addItem("Item3", "3");
When an item is selected from the combo box, I want to get its associated user data
But user types in something into the combo box, I just want to get the typed string.
if (selected_from_combobox)
return myCB->itemData(myCB->currentIndex()).toString();
else if (typed_by_user)
return myCB->currentText();
How do I differentiate between 2 cases?
You have to use 2 signals like this:
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QComboBox *myCB = new QComboBox(this);
myCB->setEditable(true);
myCB->addItem("Item1", "1");
myCB->addItem("Item2", "2");
myCB->addItem("Item3", "3");
connect(myCB,SIGNAL(currentIndexChanged(int)),this,SLOT(indexChanged(int)));
connect(myCB,SIGNAL(currentTextChanged(QString)),this,SLOT(textChanged(QString)));
}
Well, the thing is I have a tabwidget created in qtcreator, with many tabs and in the tabs there are many lineedit and other objects.
The closeable property of the tabWidget is set to true.
I execute the program and close the tabs, but when I want to reopen the tab, it's empty, I'm using this code:
tabs->addTab(new QWidget(),"TAB 1");
I want to use the same tab create on the design of qtcreator.
Your problem is that you are adding empty widget in your code:
tabs->addTab(new QWidget(),"TAB 1");
Instead you need to keep you widgets and add them like that:
QWidget* widget; // it is stored
int index = ui->tabWidget->addTab(widget, "TAB 1");
Where to take these widgets?
It is not enough to set closable to true, you also to use signal/slot:
connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
And finally:
void YourWindow::closeTab(int index)
{
// do something else
QWidget* widget = ui->tabWidget->widget(index);
ui->tabWidget->removeTab(index);
// here you can remember it and use later when adding tab
}
I want to have a line edit field in a popup menu I've got. I'm basically letting the user pick from one of several common sizes for something, but I want them to be able to enter a custom size as the last entry in the menu.
So I've got something like this (snipped from larger code, new_menu is the menu of interest):
QWidget *widget = new QWidget(new_menu);
QHBoxLayout *layout = new QHBoxLayout;
QLineEdit* le = new QLineEdit;
le->setPlaceholderText("Custom");
le->setFixedWidth(100);
ayout->addWidget(le);
widget->setLayout(layout);
QWidgetAction* wa = new QWidgetAction(new_menu);
wa->setActionGroup(group);
wa->setDefaultWidget(widget);
new_menu->addAction(wa);
connect(le, SIGNAL(returnPressed()), this, SLOT(leslot()));
Which works great, the LineEdit shows up nice and centered in the menu, it's got the placeholder text, I can click it and edit, everything. However, when I hit enter on the textBox, it emits the returnPressed signal and the menu emits a triggered signal with one of the other actions on the list, so at best I'm changing my configuration twice and at worst things break.
Additionally, when I click off the edge of the LineEdit (still in the menu though, but not in the editable area), the menu emits a triggered signal with the QWidgetAction associated with it, which isn't what I want.
So two questions:
1) Can I get the return to work the way I want. It's fine if the menu closes when it's hit, but it can't emit another action too.
2) Can I get it to not emit an action at all when the lineEdit is clicked?
Here's what I ended up doing for anyone that follows. I subclassed QLineEdit thusly:
class EnterLineEdit : public QLineEdit {
Q_OBJECT
public:
void keyPressEvent(QKeyEvent *evt) {
if (evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return) {
emit returnPressed();
} else {
QLineEdit::keyPressEvent(evt);
}
}
};
This lets me manually emit the returnPressed signal when enter/return is hit and not pass it up the widget hierarchy, so the menu never sees it when enter is hit over the lineedit. I connected the returnPressed signal to the hide() slot of the menu so that the menu will still close, but without triggering an action.
Newbie here. I want to have a GUI effect in my dock widget that whenever I click "add more" button or link, a new lineEdit field appears in the bottom.
I saw many software has something like
point-1 (_____,_____)
point-2 (_____,_____)
+ Add More Points
And when you click "+ Add More Points", a new point-3 will show up and wait for the input.
The code I have now is something like this:
#include "perfectPanel.hpp"
perfectPanel::perfectPanel(QWidget *parent) : QWidget(parent)
{
setupUi(this);
readInfo();
connect
(
btn_accept,
SIGNAL(clicked()),
this,
SLOT(readInfo()),
Qt::UniqueConnection
);
}
// Destructor
perfectPanel::~perfectPanel()
{}
void perfectPanel::readInfo()
{
xObject_ = vtkDoubleArray::New();
yObject_ = vtkDoubleArray::New();
xObject_->InsertNextValue( lineEdit_xObject01X->text().toDouble() );
xObject_->InsertNextValue( lineEdit_xObject02X->text().toDouble() );
yObject_->InsertNextValue( lineEdit_yObject01Y->text().toDouble() );
yObject_->InsertNextValue( lineEdit_yObject02Y->text().toDouble() );
}
You'll need to add that + Add More Points button to the perfectPanel class. Let's say you've already done that with this declaration in your class' private data section:
QPushButton* m_AddPoint;
Now, connect the button's clicked() signal to some slot to add the point. From the example code, you seem to already know how to do this, so I won't go into the specifics. Let's say you've connected the button's click event to the addPoint function.
void perfectPanel::addPoint()
{
/* The "this" argument is needed to prevent memory leaks */
QLineEdit* Field = new QLineEdit(this);
/* Your perfectPanel class has some layout where the existing LineEdit rows
are. I'm assuming m_Layout is a pointer to that layout here. */
m_Layout->addWidget(Field);
Field->show();
}
In Qt's QGraphicsScene, if I wanna one item, just click it, and click another selectable item will make the selected item to be unselected. If I want to select multiple items, I'd use Ctrl-key. But this maybe not convenient for some cases, then how to select multiple items without pressing Ctrl-key within QGraphicsScene?
You want to change the default behavior of QGraphicsScene, so you have to create your own scene class, inheriting QGraphicsScene.
In your class, you'll have to reimplement at least mousePressEvent and handle the item selection yourself.
Here is how you could do it (the inherited scene class is called GraphicsSelectionScene) :
void GraphicsSelectionScene::mousePressEvent(QGraphicsSceneMouseEvent* pMouseEvent) {
QGraphicsItem* pItemUnderMouse = itemAt(pMouseEvent->scenePos().x(), pMouseEvent->scenePos().y());
if (!pItemUnderMouse)
return;
if (pItemUnderMouse->isEnabled() &&
pItemUnderMouse->flags() & QGraphicsItem::ItemIsSelectable)
pItemUnderMouse->setSelected(!pItemUnderMouse->isSelected());
}
Implementing this way, clicking on an item with select it if it is not already, or will unselect it otherwise.
But be careful, implement mousePressEvent is certainly not enough : you'll have to handle the mouseDoubleClickEventas well if you don't want the default behavior.
Your scene will have to be displayed by a QGraphicsView. Here is an example of a view creating it's own scene (MainFrm class is inheriting QGraphicsView) :
#include "mainfrm.h"
#include "ui_mainfrm.h"
#include "graphicsselectionscene.h"
#include <QGraphicsItem>
MainFrm::MainFrm(QWidget *parent) : QGraphicsView(parent), ui(new Ui::MainFrm) {
ui->setupUi(this);
// Create a scene with our own selection behavior
QGraphicsScene* pScene = new GraphicsSelectionScene(this);
this->setScene(pScene);
// Create a few items for testing
QGraphicsItem* pRect1 = pScene->addRect(10,10,50,50, QColor(Qt::red), QBrush(Qt::blue));
QGraphicsItem* pRect2 = pScene->addRect(100,-10,50,50);
QGraphicsItem* pRect3 = pScene->addRect(-200,-30,50,50);
// Make sure the items are selectable
pRect1->setFlag(QGraphicsItem::ItemIsSelectable, true);
pRect2->setFlag(QGraphicsItem::ItemIsSelectable, true);
pRect3->setFlag(QGraphicsItem::ItemIsSelectable, true);
}
maybe it's a hack but it's works for me. In this example you can select multiple items using shift key
void MySceneView::mousePressEvent(QMouseEvent *event)
{
if (event->modifiers() & Qt::ShiftModifier ) //any other condition
event->setModifiers(Qt::ControlModifier);
QGraphicsView::mousePressEvent(event);
}
void MySceneView::mouseReleaseEvent(QMouseEvent *event)
{
if (event->modifiers() & Qt::ShiftModifier ) //any other condition
event->setModifiers(Qt::ControlModifier);
QGraphicsView::mouseReleaseEvent(event);
}