QLineEdit: how to handle up and down arrows? - qt

I have a console input in my Qt based application, it's a QLineEdit, all Ui is designed via QtDesigner. Is it any easy way way to handle up and down arrows in order to implement input history? The 'go to slot' only show returnProcessed signal, no way i can see to handle up and down arrows :(

you can install event filter and watch your line edit event in your window class. Below is an example:
declare event handler method on your window class:
class MainWindow : public QMainWindow {
Q_OBJECT
...
protected:
void changeEvent(QEvent *e);
...
};
window constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
...
ui->lineEdit->installEventFilter(this);
}
event handler implementation:
bool MainWindow::eventFilter(QObject* obj, QEvent *event)
{
if (obj == ui->lineEdit)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Up)
{
qDebug() << "lineEdit -> Qt::Key_Up";
return true;
}
else if(keyEvent->key() == Qt::Key_Down)
{
qDebug() << "lineEdit -> Qt::Key_Down";
return true;
}
}
return false;
}
return QMainWindow::eventFilter(obj, event);
}
hope this helps, regards

You can subclass QLineEdit and re-implement the virtual keyPressEvent method to handle your special keys.
void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Up){
// move back in history
}
else if(event->key() == Qt::Key_Down){
// move forward in history
}
else{
// default handler for event
QLineEdit::keyPressEvent(event);
}
}

I had the same problem, but I find out in other forums that you need to setFocus, e.g.:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
...
ui->lineEdit->installEventFilter(this);
this->setFocus();
}
It works for me.
Reference:
http://www.qtforum.org/article/28240/how-to-get-arrow-keys.html

For me in PyQt this was not working,
class MainWidget(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setupUi()
self->installEventFilter(self)
But this worked,
class MainWidget(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setupUi()
QtGui.QApplication.instance().installEventFilter(self)

Related

stack widget pages using pushbutton in Qt

How to navigate QStackWidget pages using QPushButtons?
Which method needs to be called whenever pushbutton is clicked, so that it opens a particluar stackwidget page.
Thanks & Regards,
QStackedWidget has a method .setCurrentIndex(int) which you can use to switch to a different page. You can use that method in combination with clicked() signal of QPushButton to change the current stacked widget page.
Example:
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
//initially set current page to 0
ui->stackedWidget->setCurrentIndex(0);
//suppose we have buttons button1 and button2
connect(button1, &QPushButton::clicked, this, [=]() {
//set page to 1
ui->stackedWidget->setCurrentIndex(1);
});
connect(button2, &QPushButton::clicked, this, [=]() {
//set page to 2
ui->stackedWidget->setCurrentIndex(2);
});
}
You can also use normal function slots instead of lambda functions:
//mainwindow.h file
class MainWindow{
//...
private slots:
void onButton1Clicked();
void onButton2Clicked();
}
//mainwindow.cpp file
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
//...
connect(button1, &QPushButton::clicked, this, &MainWindow::onButton1Clicked);
connect(button2, &QPushButton::clicked, this, &MainWindow::onButton2Clicked);
}
void MainWindow::onButton1Clicked()
{
ui->stackedWidget->setCurrentIndex(1);
}
void MainWindow::onButton2Clicked()
{
ui->stackedWidget->setCurrentIndex(1);
}

Qt window resize aspect ratio 1:1

I want to resize the app window proportionally 1:1. I tried to change it inside the ResizeEvent, but then I got the window flickering. Now my code looks like this, but it doesn't work.
filterobject.h:
class FilterObject:public QObject{
public:
QWidget *target = nullptr;//it holds a pointer to target object
int goalHeight=0;
FilterObject(QObject *parent=nullptr):QObject(parent){}//uses QObject constructor
bool eventFilter(QObject *watched, QEvent *event) override;//and overrides eventFilter function
};
widget.h:
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
virtual int heightForWidth ( int w ) const { return w*9/16;}
//virtual void resizeEvent(QResizeEvent *event) override;
~Widget();
private:
Ui::Widget *ui;
};
widget.cpp:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void QWidget::resizeEvent(QResizeEvent *event){
FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();
filter->target=targetWidget;
targetWidget->installEventFilter(filter);
}
bool FilterObject::eventFilter(QObject *watched, QEvent *event) {
if(watched != target){//checks for correct target object.
return false;
}
if(event->type() != QEvent::Resize){//and correct event
return false;
}
QResizeEvent *resEvent = static_cast<QResizeEvent*>(event);
goalHeight = 9*resEvent->size().width()/16;
if(target->height()!=goalHeight){
target->setFixedHeight(goalHeight);
}
return true;
};
Perhaps this code will work, but my condition if(event->type() != QEvent::Resize) does not work .. Any ideas?
You have some problems in your code. First of all you should install event filter once e.g in your constructor. You create an object of event filter and install it every time resizeEvent is triggered which is wrong. Also you are installing event filter on the wrong object (a new QWidget). So remove the resizeEvent function and insert in the constructor of Widget:
FilterObject *filter = new FilterObject();
filter->target=this;
installEventFilter(filter);

Unexpected behavior on QWidget while the event filtering

Just i've tested the following codes on QPushButton and on QWidget and i've encountered with different behaviors. But why?
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->widget->setStyleSheet("background:blue;");
ui->pushButton->setStyleSheet("background:blue;");
ui->widget->installEventFilter(this);
ui->pushButton->installEventFilter(this);
...
}
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
if (watched==ui->pushButton && event->type()==QEvent::Paint)
{
// Do nothing
return true;
}
else if (watched==ui->widget && event->type()==QEvent::Paint)
{
// Do nothing
return true;
}
else
return QMainWindow::eventFilter(watched, event);
}
Then, the pushButton has disappeared as normally, because i've masked its paintEvent with eventFilter. But the widget has painted to blue. Why widget hasn't disappeared.
I've solved the problem with changing QEvent::Paint with QEvent::Polish.
To who wanted the detailed description
Thanks everybody.

QGraphicsview mouserelease event does not register

I am trying to get the scene coordinates of a both a mousepress and a mouserelease event by means of an event filter.
It works fine for the mousepress, but the mouserelease seems not to be registering.
What am I missing here?
Please note I am using Qt Creator 2.2.0(based on Qt 4.7.4)
class mouseEater : public QObject{
// Q_OBJECT
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
mouseEater *eater = new mouseEater();
QGraphicsScene *scene;
scene = new QGraphicsScene();
ui->view->installEventFilter(eater);
ui->view->setScene(scene);
}
bool mouseEater::eventFilter(QObject *obj, QEvent *event){
QMouseEvent *mEvent = static_cast<QMouseEvent *>(event);
QPoint point = mEvent->pos();
cout<<"type:"<<event->type()<<endl;
switch(event->type()){
case QEvent::MouseButtonPress:
cout<<"mousepress at "<<point.x()<<","<<point.y()<<endl;
return true;
break;
case QEvent::MouseButtonRelease:
cout<<"mouserelease at "<<point.x()<<","<<point.y()<<endl;
return true;
break;
default:
//standard event processing
return QObject::eventFilter(obj, event);
break;
}
return 0;
}
The quick answer is that QGraphicsView doesn't seem to allow other QObjects to eat its mouseReleaseEvents. I'm not sure why just yet, but I think it's something to do with how mouseReleaseEvent() is reimplemented in QGraphicsView. A little hacking gives a workaround though:
HEADER:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
virtual bool eventFilter(QObject *, QEvent *);
private:
Ui::MainWindow *ui;
};
class cDerived : public QGraphicsView
{
Q_OBJECT
public:
cDerived(QWidget *parent) : QGraphicsView(parent) {}
protected:
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
};
SOURCE:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsView *View = new cDerived(ui->centralWidget);
QGraphicsScene *Scene = new QGraphicsScene(ui->centralWidget->rect(), ui->centralWidget);
View->setScene(Scene);
View->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
switch(event->type())
{
case QEvent::MouseButtonPress:
qDebug()<<"eaten mousepress";
return true;
break;
case QEvent::MouseButtonRelease:
qDebug()<<"eaten mouserelease";
return true;
break;
default:
//standard event processing
return QObject::eventFilter(obj, event);
break;
}
}
void cDerived::mousePressEvent(QMouseEvent *event)
{
qDebug()<<"mousepress";
event->ignore();
}
void cDerived::mouseReleaseEvent(QMouseEvent *event)
{
qDebug()<<"mouserelease";
event->ignore();
}
Try commenting out the 'event->ignore()' calls in the reimplemented mouse event catchers and it becomes clear how the mouseReleaseEvent() in QGraphicsView might be going wrong...
If you can reimplement QGraphicsView as a very thin class with just the constructor and mouseReleaseEvent() { event->ignore() } then you should be able to get around this bug (though, while this hack seems to be stable - suggesting that your problem might be a bug in QGraphicsView, without exhaustively looking through the QGraphicsView source we can't be sure this isn't in fact an intended feature and therefore that this hack won't break anything down the line!)
-Sam
Use QGraphicsSceneMouseEvent and the likes instead of QMouseEvent. As I found out in my question, QGraphicsScene does not dispatch normal mouse events.
Best regards

How can I move a QSlider slider handle with the keyboard?

I can't figure out how I can move a slider handle of a QSlider in QT. When I press for example A( I want to move coursor left) and D(I want move coursor right) so I did
(void) new QShortcut(Qt::Key_A, this, SLOT(moveTickmarkLeft()));
(void) new QShortcut(Qt::Key_D, this, SLOT(moveTickmarkRight()));
implementation:
void LCDRange::moveTickmarkLeft()
{
slider->setSliderPosition(slider->sliderPosition - 1);
}
void LCDRange::moveTickmarkRight()
{
slider->setSliderPosition(slider->sliderPosition + 1);
}
the same I did using function setTickPosition(), what is the difference between setSliderPosition() and setTickPosition() how can I implement my idea, thanx in advance for any help
I believe using setSliderPosition method is the correct way of moving your slider in code. setTickPosition set the way how the tick mark should be drawn, so I guess, this is not smth you need. As for intercepting keyboard events: you can install an event filter to your form ui controls and put your slider moving logic there. Below is an example. More details on event filter here
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// install event filter to ui controls of the window
ui->textEdit->installEventFilter(this);
ui->pushButton->installEventFilter(this);
ui->horizontalSlider->installEventFilter(this);
}
// event filter implementation
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::KeyPress )
{
QKeyEvent* keyEvent = (QKeyEvent*)event;
if (keyEvent->key()=='A')
{
qDebug() << "move slider";
ui->horizontalSlider->setSliderPosition(ui->horizontalSlider->sliderPosition()+1);
}
else if (keyEvent->key()=='B')
{
qDebug() << "move slider";
ui->horizontalSlider->setSliderPosition(ui->horizontalSlider->sliderPosition()-1);
}
}
return QMainWindow::eventFilter(watched, event);
}
hope this helps, regards

Resources