I'd like to have QTextEdit use hotkeys similar to readline (e.g. alt-f/b for word movements). Is there a non-intrusive way to achieve this? To be more specific, I'd like to add readline keys to telegram-desktop https://github.com/telegramdesktop/tdesktop/issues/3926
Subclass QTextEdit and override the eventFilter and implement some specialised handling for your keys.
bool YOURNEWCLASS::eventFilter(QObject *obj, QEvent *event)
{
// add code for checking for certain keys here
}
Related
I am currently working on somebody else code and I need to fix a bug linked with dynamic translation.
When the language is changed, the Loader is reloaded, it works but it generates unwanted effects (including the bug mentioned above).
So I tried to look for a way to dynamically change the translation without reloading everything.
I added m_engine->retranslate() in my switchLanguage function and this works perfectly, but only for texts directly defined in QML files. The thing is there is also a lot of text defined with setContextProperty in the C++ main controller class, and for them, it doesn't work at all (which seems pretty normal since m_engine is a QQmlApplicationEngine).
I don't see how I can simply force these texts to retranslate too. I have them in pretty much every controller function and they are used by different QML files. I am afraid that there will be no other choice but to change completely the way translation is managed. I hope advanced programmers can help me with this.
Other information:
I work with 5.13.0 version of Qt.
I don't use Designer and cannot use ui.retranslateUi().
It's hard to tell how your main controller class looks like, so here is a short general answer.
You can install an eventFilter and listen for LanguageChange.
In constructor of "main controller class", add this:
auto *core = QCoreApplication::instance();
if(core != nullptr)
{
core->installEventFilter(this);
}
Then add a function to your class:
bool MainControllerClass::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched);
if(event->type() == QEvent::LanguageChange)
{
//set properties again or emit property changed signals
}
}
actually i'm trying to get a mousePressEvent for a QFrame in QT 5 (VS2010 with Qt-Addin). Saw so many suggestons here and on other forums, but newer got it to work, or i didnt understood the princip. Also looked at the scribble example, with no luck
How can i get the mousePressEvent for a QFrame? Do i have to create a class that is inheriting from a QFrame and then initialize this frame on my own in the main()-function? isnt there a solution that i can bind it to the Qt-Designer?
tried multiple things, mostly saw something like this:
protected:
void TestQtFormsApplication::mousePressEvent(QMouseEvent *qevent)
{
if (qevent->button() == Qt::LeftButton)
{
this->close();
}
};
with this i ever got the error C2027: use of undefined type 'QMouseEvent'
Subclass QFrame and reimplement mousePressEvent(..) much like you have in your example. Remember to accept() the event to stop it propagating to the parent widget. Your error is because QMouseEvent is only forward declared in the QWidget header file, just include it yourself.
If you want to use your subclass in Qt Designer, just use a QFrame and the 'Promote' it to your subclass (docs).
The QStatusBar has just one line each time and I cannot track the history or save the history in a log file.
So I want to have a dock widget in my mainwindow that is able to display the messages I need in a multi-line way and auto-scrolling way and then automatically saved to a log file.
My question is how to do this in Qt?
If what you are looking for is something similar to the "Application Output" pane of QtCreator, then a simple QPlainTextEdit can do the job. You can call QPlainTextEdit::setReadOnly(true) if you don't want the user to be able to edit its content (i.e. only your application can write to it).
If you want auto-scrolling and automatically saving to a log file, you will need to subclass it though. Here's a little something to get you started:
#include <QCoreApplication>
class MyLogWindow : public QPlainTextEdit
{
Q_OBJECT
/* snip */
public:
void appendMessage(const QString& text);
private:
QFile m_logFile;
};
void MyLogWindow::appendMessage(const QString& text)
{
this->appendPlainText(text); // Adds the message to the widget
this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum()); // Scrolls to the bottom
m_logFile.write(text); // Logs to file
// optional if you want to see the changes
// after appendPlainText() immediately
// useful if you use this->appendMessage() in a loop
QCoreApplication::processEvents();
}
I leave it to you to deal with the boilerplate (opening and closing the file, dealing with newlines, etc.).
Now, simply put an instance of MyLogWindow in a dock in your QMainWindow, and call MyLogWindow::appendMessage() every time you need to log something to have it displayed, scrolled and saved automatically.
I'm making a Qt widget (let us call it A) that really is a subclassed QGraphicsView. However, I don't want to expose QGraphicsView methods in my widget, just the basic QWidget interface and some of my own methods. Thus, I'd like to encapsulate an instance of A as a member of a simple QWidget subclass we'll call B.
Now I wonder, what is the proper way to draw this? So far I've given B a layout whose only item is the A member. But this feels sort of wrong; for example, I'll need to override default layout settings to avoid adding extra margins etc. This leads me to feel that there is some correct way to do this that I'm missing. Any thoughts?
Edit: In the setting of RedX' answer, my question becomes: What is the proper way to use gv in this setting? Give A a layout and add gv to it, or override A's painting methods to instead use those of gv? Or something else?
I don't think there is a better way. If you don't want to use a layout, you can override the parent's resizeEvent() like this:
void A::resizeEvent( QResizeEvent* ) {
m_graphicsView->setGeometry( QRect( 0, 0, size() ) );
}
I think you are trying to do this?
class A : public QWidget{
QGraphicsView* gv; //use this to do whatever you need
};
This should expose a as a QWidget and internally you'd use the gv to do whatever you need from the QGraphicsWidget.
I have a K* window, and within it, a widget which needs the events filtered.
For example I do not want the possibility of clicking it...
How can I do that?
Have I to use eventfilters? In this case, what's the best way?
but my problem is that I can't subclass my widget,because it's a TerminalInterface->widget(), not an object like others :\
Besides the setEnabled sledgehammer approach in the first answer, there are two other approaches, one of which is to use eventfilters.
The other is to subclass the widget, and then reimplement, say, the mouse* events. Simply leaving them empty will prevent any mouse interaction. So:
MyWidget : public QSomeWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent);
protected:
void mousePressEvent(QMouseEvent *) {}
.. etc ..
};
QWidget has an enabled property. Just call widget->setEnabled(false) and this will prevent it from accepting mouse clicks. It may also modify its appearance: for example a QPushButton will be grayed out.
Event Filters sound like overkill for what you want.
It looks like eventFilter() is what you want.
Here's the section of Qt docs that talk about it:
Event Filters
Basically you have to create a class that inherits QObject and then implement the virtual function eventFilter(). Then call the installEventFilter() method on the object that you want to filter with the filter as a parameter.