How to reposition cursor to the end of the document without autoscroll
-
@lukutis222 said in How to reposition cursor to the end of the document without autoscroll:
QTextEdit does not have mouse click event;
There is https://doc.qt.io/qt-6/qwidget.html#mousePressEvent
-
@jsulm I have read about the mouseclickevent and tried the following:
In my widget.h:
class Widget : public QWidget { Q_OBJECT public: Serial* serial_local; // this will be "local" instance of the Serial object that will point to the global Serial object. Logging* logging_local; TestTool* testtool_local; Widget(Serial* serial_ptr,Logging* logging_ptr,TestTool* testtool_ptr, QWidget *parent = nullptr); ~Widget(); void fillPortsParameters(); private slots: void on_Scan_button_clicked(); void on_Serial_connect_button_clicked(); void readData(); void on_write_box_returnPressed(); void on_Scenario_select_currentIndexChanged(int index); private: Ui::Widget *ui; QString error_match; QString info_match; QString warning_match; protected: void mousePressEvent(QMouseEvent * event); };
I have added:
protected: void mousePressEvent(QMouseEvent * event);
And then In my widget.cpp I have added:
void Widget::mousePressEvent(QMouseEvent *event) { qDebug() << "Pressed"; }
Now when I click somewhere on my application I get this message printed "Pressed", however, the mouseclickevent is only registered when I click on an empty space. For example if I click anywhere on the QTextEdit window, it wont register, if I click on button "scan devices" or "connect" it will also not register.
Do I need to register an event for each widget instead of just my main Widget class?
-
@lukutis222
Indeed, because the mouse event goes to the lower-level widget you click on.Look at installing an application event filter, or on your
Widget
, for a convenient way of intercepting all mouse events, regardless of targeted widget: https://doc.qt.io/qt-6/eventsandfilters.html, https://doc.qt.io/qt-6/qobject.html#eventFilter. Otherwsie you will have to subclass and overridemousePressEvent
for every one of your widgets. -
@dan1973
Yes I figured that but its not fully clear how to do it since I do not have a seperate class for QTextEdit. Can I do that in my Widget component?Im not sure how to override QTextEdit mousePressEvent in some component (such as widget.h and widget.cpp) which does not have anything to do with QTextEdit
-
Sample appln
.h file#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QLabel> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); bool bMPress; protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; private: Ui::Widget *ui; QLabel *lbl1; }; #endif // WIDGET_H
.cpp file
#include "widget.h" #include "ui_widget.h" #include <QDebug> #include <QCursor> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); lbl1 = new QLabel("new", this); lbl1->setGeometry(20, 20, 100, 30); bMPress = false; setMouseTracking(true); } Widget::~Widget() { delete ui; } void Widget::mousePressEvent(QMouseEvent *e) { bMPress = true; QString str1 = "\n X: " + QString::number(QCursor::pos().x()) + " Y: " + QString::number(QCursor::pos().x()); qDebug() << str1; } void Widget::mouseMoveEvent(QMouseEvent *e) { if(bMPress) { QString str1 = "\n X: " + QString::number(QCursor::pos().x()) + " Y: " + QString::number(QCursor::pos().x()); lbl1->setText(str1); this->repaint(); } } void Widget::mouseReleaseEvent(QMouseEvent *e) { bMPress = false; }
-
In my widget.h file I have now declared 2 mouse click events ( one for the Widget and the other one for the QTextEdit
In my header file, there is an error because It does not allow me to use override unless the function is virtual. When I add virtual to my function declaration in cpp:
There is another error regarding the virtual function declared outside class
-
@lukutis222 What you are doing does not make sence. If you want to override mousePressEvent in QTextEdit you need to subclass QTextEdit and do it there. Just like you did with QWidget. And then you use your subclass instead of QTextEdit.
-
@jsulm Yes I understand that but I was wondering if I need to create a seperate class just for QTextEdit so I can override one function? Can I make widget class inherit from QTextEdit and then override it in my widget class if that makes sense?
-
@lukutis222 said in How to reposition cursor to the end of the document without autoscroll:
I was wondering if I need to create a seperate class just for QTextEdit so I can override one function?
Yes, this is how subclassing and overriding works.
"Can I make widget class inherit from QTextEdit and then override it in my widget class if that makes sense?" - not sure what you mean. As I sais: subclass QTextEdit and override in your subclass...
And please also read what @JonB suggested.
-
@JonB said in How to reposition cursor to the end of the document without autoscroll:
Look at installing an application event filter, or on your
Widget
, for a convenient way of intercepting all mouse events, regardless of targeted widget: https://doc.qt.io/qt-6/eventsandfilters.html, https://doc.qt.io/qt-6/qobject.html#eventFilter. Otherwsie you will have to subclass and overridemousePressEvent
for every one of your widgets.Should be pretty clear. Or you can ignore it.
-
@jsulm @JonB
JonB I do not ignore and I will definately look into this (eventfilters). I just want to learn first how to correctly override subclass methods because this is very interesting topic for me and very useful to learn. I am still learning C++ and I feel like this is very important to understand (which I struggle to do yet)Just for the sake of testing, I have created a class with a QTextEdit base class:
custom_text_edit.cpp
#include "custom_text_edit.h" custom_text_Edit::custom_text_Edit() { } void custom_text_Edit::mousePressEvent(QMouseEvent *event) { qDebug("pressed inside qtextedit \n"); }
custom_text_edit.h
#ifndef CUSTOM_TEXT_EDIT_H #define CUSTOM_TEXT_EDIT_H #include <QTextEdit> class custom_text_Edit : public QTextEdit { public: custom_text_Edit(); protected: void mousePressEvent(QMouseEvent *event) override; }; #endif // CUSTOM_TEXT_EDIT_H
I create class instance in my main.cpp:
custom_text_Edit cte;
Is there anything else I am missing? When I click on the QTextEdit widget ( my console), I still cannot trigger the mouseclick event that I just overriden
-
@lukutis222 said in How to reposition cursor to the end of the document without autoscroll:
Is there anything else I am missing?
Yes, you are still using QTextEdit in your UI. You need to replace it with your custom_text_Edit.
-
@lukutis222
Are you 100% sure you have changed yourQTextEdit
, designed in Qt Designer, over to this newcustom_text_Edit
? How did you manage that (without promoting)?Which is one reason this subclassing instead of
eventFilter()
is going to be a pain for you.... Event filter allows you to intercept events without having to subclass, which I believe is what you requested/would like. -
-
@lukutis222
Note that Qt has two means of "notifying" that something has happened. Events are just protected methods and require subclassing if you need to know about them . Signals on the other hand are public methods and you can attach slots to be notified of their occurrence without needing to subclass. (Note also that in an event you can alter the behaviour of the handling of the event, if you wish to, but in a signal you cannot, the action has already happened and you can only add your own behaviour not alter the action's existing behaviour.) For example, mouse up/down are events, but "click" is a signal; same for key presses as opposed to, say, thetextChanged()
signal after a down/up. Nobody knows the official definition/determination of when an action is exposed as a signal rather than an event, but basically the lowest level activities are events and higher level ones are signals.eventFilter()
is neither an event nor a signal. It is a method you can install as a "hook" for any low level event which may arise, allowing you either to just monitor it (as in your case) or alter what happens to it before further Qt processing. It conveniently allows any event to any widget to be intercepted without needing to subclass.