How to merge KeyReleaseEvent with Button - c++

How to merge KeyReleaseEvent and QPushButton using signal.
I mean whenever user will press enter key button should call some function using SLOT. So what i have to use in the signal?
void mywindow::keyReleaseEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_Enter:
connect(button1, SIGNAL(clicked()), this, SLOT(fileNew()));
connect(button2, SIGNAL(clicked()), this, SLOT(file()));
break;
}
}

If I understand your question correctly, you want to click some button when pressing the enter key. You can just call the QAbstractButton::click() function to perform a click.
connect(button1,SIGNAL(clicked()),this,SLOT(fileNew()));
connect(button2,SIGNAL(clicked()),this,SLOT(file())); //do this in your constructor, or somewhere else.. just make sure you only do this once
 
void mywindow::keyReleaseEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_Enter:
button1->click();
break;
}
}

There is shortcut property to handle such case.
I recommend to use QAction with shortcut value. There is lost of bonus functionality.

Related

How to set focus for button in KeyPressEvent for key_up, key_down. QT

I have a Form with buttons called "Up", "Down", etc.
I need to process keyboard buttons (arrow_up, arrow_down, etc). Parallelly I want to set focus for relevant buttons.
For Example: If I pressed the arrow_down button on keyboard then the "Down" button would be a focus on my Form.
My variant how to do this:
bool ClientWindow::eventFilter(QObject *obj, QEvent *e)
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);
switch(event->key()) {
case Qt::Key_Up: ui->up->setFocus(); ;break;
case Qt::Key_Down: ui->down->setFocus(); break;
case Qt::Key_Left: ui->left->setFocus(); break;
case Qt::Key_Right: ui->right->setFocus(); break;
}
}
return QObject::eventFilter(obj, event);
}
But, focus isn't set, and
1) If I return true from eventFilter then focus wouldn't set.
2) If I return QObject::eventFilter(obj, event) then focus would be transferred to next Object.
How to set focus for the relevant button?
Since you're trying to change a standard feature of Qt (arrow keys move focus just like TAB key does), you may want to try an extreme solution.
The point is: are your arrow key press events even being filtered at all? My guess is no. Something above (or before) the widget is consuming them and keeps the standard behavior unchanged (focus move from button to button according to their tab-indexes as usual).
I would try installing your filter onto the QApplication object, in the widget constructor this way:
qApp->installEventFilter(this);
The filter should look like this:
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
if (e->type() == QEvent::KeyPress)
{
if(qApp->activeWindow() == this)
{
QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);
switch(event->key()) {
case Qt::Key_Up: ui->up->setFocus(); break;
case Qt::Key_Down: ui->down->setFocus(); break;
case Qt::Key_Left: ui->left->setFocus(); break;
case Qt::Key_Right: ui->right->setFocus(); break;
default:
return qApp->eventFilter(obj, e);
}
return true;
}
}
return qApp->eventFilter(obj, e);
}
Please notice this line:
if(qApp->activeWindow() == this)
which should prevent the rule in the filter to be applied whenever the arrow keys get pressed (i.e. when the widget isn't the topmost one). You can ignore that, if your application hasn't other widget than this one.
Final advice: try to never change the standard UI behavior. Users do expect things to work as usual, and solutions that look absolutely cool to the developer, sometimes (often), brings no improvements at all and only confuse the user.

How to require a password to close a window?

I would like to protect a window from closing, so when the user attempts to do that, a password has to be entered in order to complete the action. There is no need for a username to be entered.
I know how to intercept the QWidget::closeEvent, as in this example:
void MainWindow::closeEvent(QCloseEvent *event) {
QMessageBox msgBox;
msgBox.setText(tr("Do you want to close the window?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No);
msgBox.setModal(true);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
event->accept();
else
event->ignore();
}
The problem is, that the example uses QMessageBox, which does not allow a text to be entered, hence it does not suit my needs.
How to modify the code in order to prompt for a password?
Solution
Instead of QMessageBox use QDialog and shape it to your needs.
Example
Here is an example I have prepared for you in order to demonstrate how the proposed solution could be implemented:
void MainWindow::closeEvent(QCloseEvent *event) {
QDialog dialog(this);
auto *layoutDialog = new QVBoxLayout(&dialog);
auto *lineEdit = new QLineEdit(&dialog);
auto *label = new QLabel(tr("Enter password to close the window:"), &dialog);
lineEdit->setEchoMode(QLineEdit::Password);
layoutDialog->addWidget(label);
layoutDialog->addWidget(lineEdit);
layoutDialog->addStretch();
connect(lineEdit, &QLineEdit::editingFinished, [&]() {
dialog.done(lineEdit->text() == "11223344");
});
dialog.resize(250, 100);
if (dialog.exec())
event->accept();
else
event->ignore();
}
Note: Of course you have to come up with a smarter way of how to keep the password safe.

Context menu on custom shortcut

I have a QGraphicsView in my MainWindow and I have a custom "grab" function on my canvas (which is the QGraphicsView inside my MainWindow) called when I press both mouse buttons.
So I want to activate my context menu only when I press CTRL + right click and prevent from activating only with a right click. It would be important to keep ActionsContextMenu policy.
Is there a way to do that?
Just check for KeyboardModifier. You can specify which modifier you want. In your case, it is the ControlModifier. Then, override the method mousePressEvent() :
void yourClass::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::RightButton &&
event->modifiers() == Qt::ControlModifier)
{
// call your context menu
}
}
If you want to use this, you'll need to call a QMenu. Just add this function in your class :
void yourClass::showMenu()
{
QMenu contextMenu(this);
QAction action("My Action", this);
contextMenu.addAction(&action);
contextMenu.exec();
}

Qt Whenever pressed enter in QTextEdit

Whenever I pressed enter in my QTextEdit it'll perform a click on my login button. Somehow this causes a crash of my QtCreator. How can I change what'll happen If I press enter in my QTextEdit?
You need to subclass QTextEdit and catch the event you're interested in by overriding the appropriate method:
class MyTextEdit : public QTextEdit
{
Q_OBJECT
public:
void MyTextEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return)
{
login(); // or rather emit submitted() or something along this way
}
else
{
QTextEdit::keyPressEvent(event);
}
}
};
Alternatively, you can install an event filter on the text edit.

How to know exactly when a user expands a QTreeView item?

Is there a way to know exactly when an expand operation begins when a user, lets say clicks the expand arrow in a QTreeView?
For the case when he double clicks I can catch the double-click event.
I tried reimplementing this slot void expand(const QModelIndex &index); from QTreeView but it doesn't seem to work.
There is a signal called void expanded(const QModelIndex &index); in QTreeView but it seems to be sent after the expansion happened.
I am using QT 4.8.2
This is what I did to get the functionality I needed:
I reimplemented the mousePressEvent from QTreeView like this
void MyTreeView::mousePressEvent(QMouseEvent *event)
{
QModelIndex clickedIndex = indexAt(event->pos());
if(clickedIndex.isValid())
{
QRect vrect = visualRect(clickedIndex);
int itemIdentation = vrect.x() - visualRect(rootIndex()).x();
if(event->pos().x() < itemIdentation)
{
if(!isExpanded(clickedIndex))
{
//do stuff
}
}
}
}
I check to see if the mouse press is left to the text label of the item(meaning on the expand arrow)
This combined with the double click event gives me what I needed.
You could try to this by implementing a method for a change event:
void YourTreeView::changeEvent(QEvent *e)
{
QFrame::changeEvent(e);
switch (e->type()) {
case QEvent::QGraphicsSceneResizeEvent
//do want you want to do
break;
default:
break;
}
}