I user QLineEdit like this, and anybody know anything is wrong:
if (event->modifiers() == Qt::ControlModifier
&& event->key()== Qt::Key_A) {
qDebug() << "Ctrl+A pressed";
m_lineEdit->setFocus(Qt::ShortcutFocusReason);
m_lineEdit->selectAll();
}
Try to use timer to make sure all events are processed and then selection is done:
QTimer::singleShot(0, m_lineEdit, SLOT(selectAll()));
instead of m_lineEdit->selectAll();
Related
In my current application, I need to make QT close a window by pressing Shift + Eesc or by pressing Esc 3x.
First, I tried Shift + Esc, it went this way
if ((event->key() == Qt::Key_Escape) && (event->key() == Qt::Key_Shift))
{
cout << "test" << endl;
on_close_x_button_clicked();
}
But for some reason, it just doesn't work. I googled it and found something about a QKeySequence but I didn't find any example of how to do it properly. I tried some ways with no success like:
if ((event->key() == Qt::QKeySequence(Qt::Key_Escape + Qt::Key_Shift)))
{
cout << "teste" << endl;
on_close_x_button_clicked();
}
}
But again, no dice. Can someone point me how to proper implement this functionality?
I also could not find anything that allowed me to create an event based on pressing Escape key 3x. Can someone, please, also teach me how to do it?
I also tried using Shortcuts, and it went like this:
LinAdvancedTestWidget::LinAdvancedTestWidget(QWidget *parent,
QObject *event_filter,
SystemEvent *event, int dpi)
: AdvancedTestWidget(parent, event_filter, event) {
(void)dpi;
KeyShiftEsc = new QShortcut(this);
KeyShiftEsc->setKey(Qt::Key_Shift + Qt::Key_Escape);
connect(KeyShiftEsc, SIGNAL(activated()), this, SLOT(slotShortcutShiftEsc()));
}
void LinAdvancedTestWidget::slotShortcutShiftEsc()
{
cout << "Escape LinAdvancedTestWidget" << endl;
on_close_x_button_clicked();
}
But it again, also does not work :/
Shift is a modifier, not a key, as you seem to compare. You would need to write something like this:
if ((event->key() == Qt::Key_Escape) && (event->modifiers() & Qt::Key_Shift))
{
...
}
Also, it is better if you use the QWidget::addAction(...) method as:
QAction *action = new QAction("my action", "Shift+Esc");
myWidget->addAction(action);
You can also set multiple shortcuts on an action:
action->setShorcuts({"Shift+Esc", QKeySequence(Qt::Key_Esc, Qt::Key_Esc, Qt::Key_Esc)});
Im beginner in qt and i do my first project. I am encountering a problem.
I put somes edit line in a scroll area. All of this edit text should countains path to files. To make this app more userfriendly i decided to implement a drag and drop. By this way, users can just take a file from their explorer and drop it to line edit which will be fill with the path of the file.
My problem is: When i try to drop, all edit line where my mouse passed on, will be fill with the path of the file. If i change if statements by else if, its the first edit line that my mouse passed on which will be fill but not the one where my mouse is at the moment of the drop.
here the code:
void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
e->accept()
}
void MainWindow::dropEvent(QDropEvent *e)
{
foreach (const QUrl &url, e->mimeData()->urls()) {
QString fileName = StringManagement::getDir(url.toLocalFile());
if(ui->lineEdit->underMouse())
ui->lineEdit->setText(fileName);
if(ui->lineEdit_2->underMouse())
ui->lineEdit_2->setText(fileName);
if(ui->lineEdit_5->underMouse())
ui->lineEdit_5->setText(fileName);
if(ui->lineEdit_9->underMouse())
ui->lineEdit_9->setText(fileName);
if(ui->lineEdit_10->underMouse())
ui->lineEdit_10->setText(fileName);
if(ui->lineEdit_11->underMouse())
ui->lineEdit_11->setText(fileName);
}
}
On other point that i dont really understand is:
<pre><code>void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
qInfo() << "enter";
e->accept();
}
void MainWindow::dragLeaveEvent(QDragLeaveEvent *e){
qInfo() << "leave";
e->accept();
}
when i put my mouse on an edit line and i stay on it, i will see both message in the console... i expected to see the first one when my mouse enter in and the second one when my mouse leave it.
thank you in advance for your helps.
Following your answer to my comment I'll try to help you.
I'm not an expert at Qt so I may be wrong but since there is no answer yet I'll try to give one.
I tried to reproduce your code and for the second question:
void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
qInfo() << "enter";
e->accept();
}
void MainWindow::dragLeaveEvent(QDragLeaveEvent *e)
{
qInfo() << "leave";
e->accept();
}
I have the same behaviour if MainWindow and the lineEdits both manage drag and drop (setAcceptDrops(true)). I think that you "enter" when you enter the MainWindow and then "leave" when you enter the lineEdit since it manages itself the drag and drop.
If you set :
ui->lineEdit->setAcceptDrops(false);
Then you don't "leave" anymore.
For the first part
If I try to reproduce your code, I have a problem with the underMouse() function.
Maybe your problem comes from here?
If I implement my own underMouse() then everything is fine.
I hope someone else with better Qt knowledge will come to your help.
Ok i find a solution. I dont really like it because i dont find it really clean but that works. If others have cleaner solution im open to it. I put my solution here. Maybe that could help someone in the future. I finaly didn't use drop methode but i used an eventFilter which give me the posibility to have a better management of events.
<pre><code>MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
this->data = DataModel::GetInstance();
ui->setupUi(this);
setAcceptDrops(true);
//ui->lineEdit->dragEnabled();
//ui->lineEdit->setAcceptDrops();
installEventFilter(this);
ui->lineEdit->installEventFilter(this);
ui->lineEdit_2->installEventFilter(this);
ui->lineEdit_5->installEventFilter(this);
ui->lineEdit_9->installEventFilter(this);
ui->lineEdit_10->installEventFilter(this);
ui->lineEdit_11->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
qInfo() << "enter";
e->accept();
}
bool MainWindow::eventFilter(QObject* obj, QEvent* event){
if(event->type() == QEvent::DragEnter){
if(obj == ui->lineEdit){
this->flag = 1;
}
else if(obj == ui->lineEdit_2){
this->flag = 2;
}
else if(obj == ui->lineEdit_5){
this->flag = 3;
}
else if(obj == ui->lineEdit_9){
this->flag = 4;
}
else if(obj == ui->lineEdit_10){
this->flag = 5;
}
else if(obj == ui->lineEdit_11){
this->flag = 6;
}
qInfo()<<"flag" <<this->flag;
}
if(event->type() == QEvent::Drop){
qInfo()<< obj;
QDropEvent *drop = static_cast<QDropEvent *>(event);
foreach (const QUrl &url, drop->mimeData()->urls()) {
QString fileName = StringManagement::getDir(url.toLocalFile());
qInfo()<<"flag drop" <<this->flag;
if(this->flag == 1){
ui->lineEdit->setText(fileName);
}
else if(this->flag == 2){
ui->lineEdit_2->setText(fileName);
}
else if(this->flag == 3){
ui->lineEdit_5->setText(fileName);
}
else if(this->flag == 4){
ui->lineEdit_9->setText(fileName);
}
else if(this->flag == 5){
ui->lineEdit_10->setText(fileName);
}
else if(this->flag == 6){
ui->lineEdit_11->setText(fileName);
}
return true;
}
}
}
</code></pre>
I dont manage return in the filter for now but the idea is here.
How can I simulate user interaction (key press event) in Qt?
I tried the same approach, but not able to get written on the lineEdit widget
ui->lineEdit->setFocus();
QKeyEvent *key_press = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_X, Qt::NoModifier);
QApplication::sendEvent(ui->lineEdit, key_press);
Alternately
QApplication::postEvent(ui->lineEdit, key_press);
also didn't succeed.
I tried the below also and didn't get any result.
QKeyEvent key(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier);
QApplication::sendEvent(ui->lineEdit, &key);
if (key.isAccepted()) {
qDebug()<<"everything is ok";
} else {
qDebug()<<"something wrong";
}
Please suggest what am I missing.
Regards,
Sayan
In the link you indicate an enter is given so the text is not necessary, but in the case you want to send a letter you must pass that parameter:
ui->lineEdit->setFocus();
QKeyEvent *key_press = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X");
// text ─────┘
QApplication::sendEvent(ui->lineEdit, key_press);
A user can step through the widgets of QtGUI via key "Tab" or via arrow keys "<-" and "->".
Does anybody know how to disable the arrow keys for this purpose? I need the arrow keys for something else.
You would need to reimplement the corresponding event in your own QWidget subclass as follows:
bool MyWidget::keyPressEvent(QKeyEvent *keyEvent)
{
if (keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right) {
// Do nothing
} else {
QWidget::keyPressEvent(keyEvent);
}
}
Just reimplement event() or keyPressEvent() / keyReleaseEvent() of main window. In reimplemented methods you can place your desired actions.
I may use QAction for this purpose. So you wont need subclassing.
QTabBar *tabBar;
........................
QAction* pLeftArrowAction = new QAction(this);
pLeftArrowAction->setShortcut(Qt::Key_Left);
QAction* pRightArrowAction = new QAction(this);
pRightArrowAction->setShortcut(Qt::Key_Right);
tabBar->addActions(QList<QAction*>() << pLeftArrowAction << pRightArrowAction);
I'm attempting to forward all key press events from my QGraphicsView to a widget that is currently on the scene.
My QGraphicsView looks like this:
Character_controller::Character_controller(Game_state * game_state) : Game_base_controller(game_state) {
this->character = new Character(this->game_state);
this->scene->addWidget(this->character);
connect(this, SIGNAL(keyPress(QKeyEvent *)), this->character, SLOT(update()));
}
And then, my character which subclasses QWidget, which should recieve all keypress events
Character::Character(Game_state * game_state) : Base_object(game_state) {
}
Character::~Character() {
}
void Character::update() {
cout << "HELLO FROM TIMER CONNECTED ITEM" << endl;
}
For some reason, this isn't working. How can I forward all keypress events from the view to my character?
The error I get is this:
Object::connect: No such signal game::Character_controller::keyPress(QKeyEvent *) in implementation/game_controllers/character_controller.cpp:21
keyPress(QKeyEvent*) doesn't exist as a signal, hence the error message that you're getting. As such, you can't do this:
connect(this, SIGNAL(keyPress(QKeyEvent *)), this->character, SLOT(update()));
In order to capture key press events in your graphics view, you will need to override the keyPressEvent function:
void Character_controller::keyPressEvent(QKeyEvent* event)
{
// Call functions on your character here.
switch (event->key())
{
case Qt::Key_A:
character->moveLeft(); // For example
break;
case Qt::Key_D:
character->moveRight(); // For example
break;
...
}
// Otherwise pass to QGraphicsView.
QGraphicsView::keyPressEvent(event);
}
You could just pass the QKeyEvent to the character to manage its own key presses, but you might find it difficult to ensure that different items in your scene don't rely on the same key(s) if you don't keep all your key press handling code in one place.
You have to override the keyPressEvent event to capture key press events