Qt: cursor blinking cause repaint of parent widget? - c++

Bellow you can see minimal example code to demonstrate problem.
If you run it and give focus to QLineEdit, you get output every second: paintEvent, paintEvent and so on.
I can not understand why MyW::paintEvent called on every
cursor blinking in child widget? As you see I do not configure QLineEdit,
by default on my linux box it have no transparent elements,
but still for some reason cursor cause all widgets to redraw their content?
#include <QApplication>
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
#include <QLineEdit>
class MyW final : public QWidget {
public:
MyW() {
//setAutoFillBackground(false);
}
void paintEvent(QPaintEvent *e) {
e->accept();
qDebug("paintEvent");
QPainter painter{this};
painter.fillRect(rect(), Qt::green);
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyW w;
w.resize(600, 600);
w.show();
auto le = new QLineEdit{&w};
le->show();
return app.exec();
}

Related

Fill background outside window QT

I have read a documentation and aswell many sites on website.
Unfortunatly I didn't find answer to my question.
Is there any chance(I believe there is) to fill background outside the popup window? Let me explain: If i have window like of my whole app with resolution 500x500 [px] and I create a popup window 300x300 in the middle - it means I have 200 px in each side "parent-window". Is there any chance (method, flag) to fill background in gray color?
Image: https://imgur.com/Hunev58
Modifying the palette does the job. Here you get a purple background when the MessageBox is shown , and come back to normal once clicked
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include <QPalette>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
QVBoxLayout mainLayout;
QLabel foolabel("FooLabel");
QPushButton foobutton("FooButton");
mainLayout.addWidget(&foolabel);
mainLayout.addWidget(&foobutton);
QWidget window;
window.setLayout(&mainLayout);
w.setCentralWidget(&window);
QPalette palette = QApplication::palette(&w);
palette.setColor(QPalette::Inactive,QPalette::Window,QColor(138,43,226));
w.setPalette(palette);
w.show();
QMessageBox box(&w);
box.exec();
return a.exec();
}

QDialog expanding base on the QLabel content

I'd like to show and then close a dialog after 5 seconds. The dialog needs to be automatically resized (horizontally and vertically) based on the content of a label. Here is my code:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
void notify (int intTime=1000)
{
QDialog notify;
notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel(&notify);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
notify.adjustSize();
QTimer::singleShot(intTime, &notify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}
It does not not expand the dialog based on the label size. Here is how it looks:
How can I fix it? (Please also let me know if there is better way of doing this.)
I am using Qt5 in Linux.
Since you have not used a QLayout the QLabel will be displayed as large as you can, a possible request is to change the size of QDialog to the recommended size of QLabel with sizeHint():
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
void notify (int intTime=1000)
{
QDialog notify;
notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel(&notify);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
notify.resize(lbl->sizeHint());
QTimer::singleShot(intTime, &notify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}
The other possible solution is to use a QLayout:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
#include <QVBoxLayout>
void notify (int intTime=1000)
{
QDialog notify;
QVBoxLayout *lay = new QVBoxLayout(&notify);
//notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel;
lay->addWidget(lbl);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
QTimer::singleShot(intTime, &notify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}

move QGraphicsView around QGraphicsScene

I'm making a side view drag racing game in QT c++. I want to move my view around my scene from left to right. I have the scene set to 3600x800, but i want the view the be at the far left of my scene not at the center at the start. When i press W on my keyboard I want the view to move to the left for 1px. How do I do that? I can't find anything online
scene=new QGraphicsScene(this);
view = new QGraphicsView;
scene->setSceneRect(0,0,3600,800);
view->setScene(scene);
You will never find something so particular on the internet, you should look for each part separately:
If you want it to appear on the left side then you must use horizontalScrollBar() of the GraphicsView when it is displayed, we can do that with the showEvent method.
if you want to do an action when you press any key you could overwrite the keyPressEvent method.
To move the sceneRect() you must make a copy, move it and set it again.
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QKeyEvent>
#include <QScrollBar>
class GraphicsView: public QGraphicsView{
public:
using QGraphicsView::QGraphicsView;
protected:
void keyPressEvent(QKeyEvent *event){
if(event->key() == Qt::Key_W){
if(scene()){
QRectF rect = scene()->sceneRect();
rect.translate(1, 0);
scene()->setSceneRect(rect);
}
}
}
void showEvent(QShowEvent *event){
QGraphicsView::showEvent(event);
if(isVisible()){
horizontalScrollBar()->setValue(0);
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
GraphicsView view;
scene.setSceneRect(0,0,3600,800);
view.setScene(&scene);
scene.addRect(0, 200, 400, 400, Qt::NoPen, Qt::red);
view.show();
return a.exec();
}

Overlay while loading page into QWebView

Let's say we have a barebones QWebView:
#include <QApplication>
#include <QWebView>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QWebView view;
view.show();
view.setUrl(QUrl("http://google.com"));
return app.exec();
}
How can I display a graphic overlay, preferably fullscreen with transparency and minimal animation (like timer/beachball/etc.) from when the page starts loading till it's finished? Should also be triggered when url changes from within the QWebView.
You can use the LoadingOverlay class provided in this answer to draw an overlay over any QWidget. In your case, show the overlay on top of the QWebView when the signal loadStarted is triggered and hide it, when the signal loadFinished is triggered.
The following code should get you started. I put the code from the linked answer into overlay.h, the subclass of QWebView which handles the showing/hiding of the overlay is in webview.h:
webview.h
#include "overlay.h"
#include <QWebView>
class WebView : public QWebView
{
Q_OBJECT
public:
WebView(QWidget * parent) : QWebView(parent)
{
overlay = new LoadingOverlay(parent);
connect(this,SIGNAL(loadFinished(bool)),this,SLOT(hideOverlay()));
connect(this,SIGNAL(loadStarted()),this,SLOT(showOverlay()));
}
~WebView()
{
}
public slots:
void showOverlay()
{
overlay->show();
}
void hideOverlay()
{
overlay->hide();
}
private:
LoadingOverlay* overlay;
};
main.cpp
#include <QApplication>
#include "overlay.h"
#include "webview.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ContainerWidget base;
Webview w(&base);
base.show();
w.load(QUrl("http://google.com"));
return a.exec();
}

QT zoom to Polygon

i have a fixed size QGraphicsview and my own class QGraphWidget class
GraphWidget::GraphWidget(QWidget *parent)
:QGraphicsView(parent)
{
QGraphicsScene *scene = new QGraphicsScene(this);
setScene(scene);
scale(1,-1);
setWindowTitle(tr("Poly"));
}
void GraphWidget::showPoly(){
scene()->clear();
scene()->setSceneRect(QRectF());
QPolygonF polygon;
QPen pen(Qt::black,1);
QBrush brush(Qt::black);
brush.setStyle(Qt::SolidPattern);
polygon<< QPointF(0,0)<< QPointF(10,0)<< QPointF(15,20)<<QPointF(5,10);
;
QGraphicsPolygonItem *polyItem=scene()->addPolygon(polygon,pen);
fitInView(polyItem);
}
It is possible that the scene focus the polygon and zoom it ?
I tried fitinView() or setSceneRect() but nothing worked, the polygon is still very small.
EDIT
with fitInView(polyItem->boundingRect());
The problem is that my QGraphicsview is fixed, so the fit in view has to zoom in. It can't change the size of the Qgraphicsview
So i got the answer.
The problem was that i called showPoly() inside of the constructor. But on this moment the size of the Qgraphicsview was not fixed.
I use a work around with QSingleShot
#include "mainwindow.h"
#include <QApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
QTimer::singleShot(1, &w,SLOT(callShowPoly()));
return a.exec();
}