Draw a line over a video in a QGraphicsScene - c++

I'm new to Qt and I'm having some troubles.
I'm trying to draw a simple line on a video, like an overlay, when i click on a button.
My video is from a camera, and it is displayed into a QGraphicsScene (or Qframe), it's a live video.
I tried to modify the paintEvent, but the line emerges and disapear when a new frame comes.
I also tried to create an Overlay class, with some attributes (WA_NoBackGround and WA_PaintOnScreen), but this time the line emerges on the video, but the video stops.
Here is my code for the overlay ( inspired by Draw Rectangular overlay on QWidget at click ):
Overlay.h
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPointer>
class Overlay : public QWidget
{
public:
Overlay(QWidget * parent = 0) ;
protected:
void paintEvent(QPaintEvent *e );
};
Overlay.cpp
#include "overlay.h"
Overlay::Overlay(QWidget *parent): QWidget (parent)
{
//setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_NoBackground);
setAttribute(Qt::WA_PaintOnScreen);
}
void Overlay::paintEvent(QPaintEvent *e)
{
QPainter p(this);
p.drawLine(0,0,100,100);
}
The clickDraw button slot :
QPointer<Overlay> m_overlay;
w= static_cast<QWidget*>(ui->r_frame);
if (!m_overlay)
m_overlay = new Overlay(w->parentWidget());
m_overlay->setGeometry(w->geometry());
m_overlay->show();
update();
I'm on linux embedded, with Qt 4.8.6
EDIT
I tried to create a transparent Qwidget (setOpacity), with the QGraphicsView object as parent, but it did not work, the widget appears white. I think i need a composition manager for X11 (it is what i read from various websites).
Thanks for your help,
Greetings

For this to work properly you need to use the Qt-provided functionality:
Use a VideoGraphicsItem for playing video, as explained in this fine tutorial: http://doc.qt.io/qt-5/qtmultimedia-multimediawidgets-videographicsitem-example.html
Use a QGraphicsLineItem to add a line to your scene.
Note that Qt Multimedia comes with GStreamer backend, so it should be easy to incorporate your existing GStreamer input.

Related

Removing titlebar from Qt window while keeping the default window borders

I'm trying to remove the default Windows titlebar from my Qt window (QT version 5.12.2 and using C++) while still keeping the window borders. I've more or less achieved this using the flag Qt::CustomizeWindowHint. However, this changes the window borders to white lines instead of the default borders.
Example of how the borders look AFTER I've applied the Qt::CustomizeWindowHint flag:
As you can see, these are not the normal Windows window borders.
How can I change/edit these boders (i.e. change their color) or how am I able to keep the default Windows window borders while removing the titlebar?
Here's a minimal reproducible example:
main.cpp:
int main(int argc, char* argv[]) {
QApplication application(argc, argv);
launcher mainWindow;
//debugChecks();
mainWindow.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::MSWindowsFixedSizeDialogHint);
mainWindow.setWindowTitle("Test");
mainWindow.show();
return application.exec();
}
launcher.h
#pragma once
#include <QtWidgets/QMainWindow>
#include <QMouseEvent>
#include <QPoint>
#include "ui_launcher.h"
class launcher : public QMainWindow {
Q_OBJECT
public:
launcher(QWidget* parent = Q_NULLPTR);
private:
Ui::launcherClass ui;
void mousePressEvent(QMouseEvent* eventVar);
void mouseMoveEvent(QMouseEvent* eventVar);
int mouseClickX = 0;
int mouseClickY = 0;
};
launcher.cpp
#include "launcher.h"
launcher::launcher(QWidget* parent) : QMainWindow(parent) {
ui.setupUi(this);
}
void launcher::mousePressEvent(QMouseEvent* eventVar) {
mouseClickX = eventVar->x();
mouseClickY = eventVar->y();
}
void launcher::mouseMoveEvent(QMouseEvent* eventVar) {
move(eventVar->globalX() - mouseClickX, eventVar->globalY() - mouseClickY);
}
Your description isn't really clear. One should not be using a QMainWindow for a logon/in dialog. Having said that I created an application on Ubuntu 20.04 (should build fine for you as I used qmake). You can download the project zip here. When the application starts it looks like this:
After clicking on "golden" it looks like this:
After Green it looks like this:
After clicking on Freaky it looks like this:
Please note that FramelessWindowHint not only removes the title bar and system menu along with window frame, it also removes your ability to resize/drag/move the window.
My apologies for not taking out the StackOver1.pro.user file. Didn't think about it until just now. You will need to delete that or it could hose your build.
QPalette and QStyle for Border
Palette Can Change window styles and colors of the Application. and for Reference
https://doc.qt.io/archives/qt-5.7/qtwidgets-widgets-styles-example.html
You can do something like this
self.setWindowTitle("‎") # Python
‎
mainWindow.setWindowTitle(""); # C/C++
but instead of passing an empty string, pass an empty character. This one worked for me: https://emptycharacter.com/

QDialog with transparent background shows up as black

I have QDialog, which is modal and takes the whole screen, meaning it spans itself across all the monitors and I want to make it transparent. Initially I went setWindowOpacity() and it worked, but after that everything else I would draw on the dialog using QPainter it would draw opaquely, which was understandable. Because this wasn't the solution I was looking for I ended up doing setAttribute(Qt::WA_TranslucentBackground) and to my surprise the background ended up being black. The same thing happens when I do setStyleSheet("QDialog {background-color: transparent;}"). Has anyone else seen this issue and how do I fix it?
Some code snippets:
SnipAreaDialog::SnipAreaDialog(QWidget *parent) : QDialog(parent) {
setAttribute(Qt::WA_TranslucentBackground);
setCursor(Qt::CrossCursor);
}
void SnipAreaDialog::showEvent(QShowEvent *event) {
auto desktopRect = qApp->desktop()->geometry();
setGeometry(desktopRect);
QDialog::showEvent(event);
}
Also, I am showing the dialog with QDialog::exec() and I tried setting its parent to 0, as well as to the main window of my app, it's the same behavior.
Yes, I also had a situation, try like this, it helped me...
example below
#include <QApplication>
#include <QDialog>
class Dialog : public QDialog
{
public:
Dialog() : QDialog(0, Qt::FramelessWindowHint)
{
setAttribute(Qt::WA_TranslucentBackground);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog d;
d.showFullScreen();
return a.exec();
}
if there isn't a parent, you may consider using
Qt::WindowStaysOnTopHint as well. If the window system supports it, a
tool window can be decorated with a somewhat lighter frame. It can
also be combined with Qt::FramelessWindowHint .

Qt create prototype tool for mobile device

Hi I need to create prototype tool for smartphone screen using Qt, I have png image of the smartphone right now and need to do place some text and image as shown in below image.
So my question is, is there anything similar already exist to create such a tool in C++ Qt.
Or do I need to use QPainter for achieving it.
Or any better method to accomplish it.
I can give you small code example how you can create such app. For main window you can set brush, created from this image, then set mask for window to ensure it painting right way. Also you need set Qt::FramelessWindowHint flag. Then you can add all needed widgets to this widget. Small example (assuming :/img/i.png is your picture, saved to resources):
At .h file:
#include <QFrame>
#include <QPixmap>
class TestFrame : public QFrame
{
Q_OBJECT
public:
TestFrame(QWidget* p = 0);
protected:
void resizeEvent(QResizeEvent* e) override;
private:
QPixmap _pix;
};
At .cpp file:
#include <QBitmap>
TestFrame::TestFrame(QWidget *p) :
QFrame(p, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint),
_pix(":/img/i.png")
{
QPalette pal = palette();
pal.setBrush(QPalette::Background, QBrush(_pix));
setPalette(pal);
resize(_pix.width(), _pix.height());
}
void TestFrame::resizeEvent(QResizeEvent *e)
{
QFrame::resizeEvent(e);
setMask(_pix.scaled(size()).mask());
}
Also make sure your image has alpha-channel for invisible parts (I mean corners). For now it hasn't.

QFrame with background image and otherwise transparent background

I am making a desktop carousel app. There I need to show image widgets, which might contain other sub-widgets as well. For that I am using a QFrame with the required image as background. Here is the image I am trying to use: image link. What I want is that only the image shows up, no background image or anything shows up as well, so to the user it looks like just the image. Here is my code:
setGeometry(QRect(100, 20, 325,400));
setFrameStyle(QFrame::StyledPanel);
setStyleSheet("QFrame#ImageFrame { background-color: transparent; background: url(:icon/ipad-skin); }");
setAutoFillBackground(false);
However, I am getting this as a result:
I tried this as well (obtained from here) (and removing the stylesheet):
void MyWidget::paintEvent(QPaintEvent *p)
{
QPainter* pPainter = new QPainter(this);
pPainter->drawPixmap(rect(), QPixmap(":icon/newskin.png"));
delete pPainter;
QWidget::paintEvent(p);
}
Nothing different, the exact same result. The greyness of the background still shows.
How do I make the grey background of the QFrame go and display only the image (the dimensions I am setting are the same as the image)?
P.S I am aware that similar questions hve been answered here: QWidget transparent background (but not the children), and here: Frameless and transparent window qt5 but these doesn't solve my problem. The last solution makes my QFrame look like this:
The QFrame now comes with a title bar which is anything but what I wanted in the first place.
Edit - This solution works, but in my use-case, I need to display an image that is rendered via GL inside the QFrame (specifically, in the viewport within the iPad image we can see here). In Windows, setting the Qt::WA_TranslucentBackground property makes that GL-rendered image invisible. It works fine in Mac, though. So I am looking for a solution which will work in Windows as well.
This code works for me (tested under MacOS/X 10.10.3, using Qt 5.5.0-beta; I'd expect it to work under any Qt version 4.5.0 or higher though):
main.h:
#ifndef main_h
#define main_h
#include <QFrame>
#include <QPixmap>
class MyFrame : public QFrame
{
public:
MyFrame(QWidget * parent);
virtual void paintEvent(QPaintEvent * e);
private:
QPixmap _pixmap;
};
#endif
main.cpp:
#include <QApplication>
#include <QPainter>
#include "main.h"
MyFrame :: MyFrame(QWidget * parent) : QFrame(parent, Qt::Window|Qt::FramelessWindowHint)
{
setAttribute(Qt::WA_TranslucentBackground);
_pixmap.load("/Users/jaf/iPad_Vector.png");
resize(_pixmap.size());
}
void MyFrame :: paintEvent(QPaintEvent * /*e*/)
{
QPainter p(this);
p.drawPixmap(0,0,width(),height(), _pixmap);
}
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
MyFrame f(NULL);
f.show();
return app.exec();
}
Screenshot (showing the app's window in front of my desktop background):
Can you try this light modification to your code ?
In case it doesn't work can you publish your compilable code on a public repository ? This would help reproduce in your exact context.
void MyWidget::paintEvent(QPaintEvent *p)
{
QPainter* pPainter = new QPainter(this);
pPainter->setBackgroundMode(Qt::TransparentMode);
pPainter->drawPixmap(rect(), QPixmap(":icon/newskin.png"));
delete pPainter;
QWidget::paintEvent(p);
}

QDockWidget causes qt to crash

I Have the version of Qt that is built into ubuntu 11.10. And am trying to use a QDockWidget that cannot actually dock (basically, I just want a window that floats. I don't want to just make the view be a top level view because then I would have the OS window bar up there, which I don't want, and if I were to hide it, then the window won't be movable).
So, I basically make a new Qt Gui project, and don't change any of the files, except for the mainwindow.cpp file, which I change to:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDockWidget>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDockWidget *dockWidget = new QDockWidget(this);
// Without window management and attached to mainwindow (central widget)
dockWidget->setFloating( true );
// resize by frame only - not positional moveable
dockWidget->setFeatures( QDockWidget::DockWidgetMovable );
// never dock in mainwindow
dockWidget->setAllowedAreas( Qt::NoDockWidgetArea );
// title
dockWidget->setWindowTitle( "Dock Widget" );
// add contents. etc etc....
dockWidget->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
The problem is that when I go to move the widget, the whole program crashes. I want to know if I am doing something very wrong, or if there is just a bug in qt.
You made the widget floating but not floatable.
dockWidget->setFeatures( QDockWidget::DockWidgetMovable |
QDockWidget::DockWidgetFloatable );
And you can also have a movable frameless window, by handling the mouse dragging yourself through mousePressEvent, mouseReleaseEvent and mouseMoveEvent.
How to hide the now useless float button
Based on QDockWidget source code, the "float button" is not shown if there is a title bar widget:
dockWidget->setTitleBarWidget(new QLabel("Dock Widget", dockWidget));
Or since it has a name (which isn't documented), you can hide it explicitly:
QAbstractButton * floatButton =
dockWidget->findChild<QAbstractButton*>("qt_dockwidget_floatbutton");
if(floatButton)
floatButton->hide();