QGraphicsView cannot render video when there is a QWebEngineView - qt

I am making a very simple application which plays a video using QMediaPlayer/QGraphicsVideoItem/QGraphicsScene/QGraphicsView and in the meantime, it displays a web page using QWebEngineView.
However, when the QWebEngineView shows, only the sound of the video is played. The widget shows only white. When QWebEngineView's ->show() is not called, the video plays normally.
I've tried QVideoWidget. It doesn't have such problem.
I'm thinking that the rendering of the QGraphicsView might have conflicts with QWebEngine's.
Here's the code:
#include "mainwindow.h"
#include <QApplication>
#include <QWebEngineView>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMediaPlayer>
#include <QVideoWidget>
#include <QGraphicsVideoItem>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWebEngineView *webview = new QWebEngineView();
QMediaPlayer *player = new QMediaPlayer();
QGraphicsVideoItem *item = new QGraphicsVideoItem;
QVideoWidget *vwid = new QVideoWidget();
QGraphicsView *gview = new QGraphicsView();
player->setMedia(QUrl::fromLocalFile("/home/user/Videos/IMG_6201.MOV"));
//player->setVideoOutput(vwid);
player->setVideoOutput(item);
QGraphicsScene *gscene = new QGraphicsScene();
gview->setScene(gscene);
webview.setUrl(QUrl("https://www.google.com"));
gview->scene()->addItem(item);
//vwid->show();
player->play();
webview->show();
gview->show();
return a.exec();
}

Related

Can we include and show some others widgets in a QVideoWidget? [duplicate]

everyone! I try to set a click property to a QMediaPlayer Element, but I can not find the mode to make it, and if I try to put a button in front to Video, the button puts behind to video, even with
button->raise();
videoWidget->lower();
And If I put a Button to fullscreen the screen turns in black and don't shows the video
this id the code of the video player
QMediaPlayer *player = new QMediaPlayer(this);
QVideoWidget *vw = new QVideoWidget(this);
QMediaPlaylist *PlayList = new QMediaPlaylist(this);
PlayList->addMedia(QUrl::fromLocalFile("/home/user/Videos/video.mp4"));
PlayList->setPlaybackMode(QMediaPlaylist::Loop);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(vw);
player->setVideoOutput(vw);
player->setPlaylist(PlayList);
vw->setGeometry(0,0,800,480);
vw->show();
player->play();
One possible solution is to create a widget where the QVideoWidget is placed through a layout, the button is also added and we change the position through the resizeEvent() event.
#include <QApplication>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QPushButton>
#include <QUrl>
#include <QVBoxLayout>
#include <QVideoWidget>
#include <QDebug>
class VideoWidgetButton: public QWidget{
QPushButton *btn;
QVideoWidget *vw;
QMediaPlayer *player;
public:
VideoWidgetButton(QWidget *parent=Q_NULLPTR):QWidget(parent){
setLayout(new QVBoxLayout);
layout()->setContentsMargins(0, 0, 0, 0);
vw = new QVideoWidget(this);
btn = new QPushButton(this);
btn->setIcon(QIcon(":/icons/tux.jpeg"));
btn->resize(QSize(128, 128));
btn->setIconSize(QSize(128, 128));
connect(btn, &QPushButton::clicked, [](){
qDebug()<<"clicked";
});
layout()->addWidget(vw);
player = new QMediaPlayer(this);
player->setVideoOutput(vw);
QMediaPlaylist *playList = new QMediaPlaylist(this);
playList->addMedia(QUrl("qrc:/video/SampleVideo_1280x720_1mb.mp4"));
playList->setPlaybackMode(QMediaPlaylist::Loop);
player->setPlaylist(playList);
player->play();
}
protected:
void resizeEvent(QResizeEvent *ev){
btn->move(rect().bottomRight()-btn->rect().bottomRight());
return QWidget::resizeEvent(ev);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VideoWidgetButton w;
w.resize(640, 480);
w.show();
return a.exec();
}
The complete example can be found in the following link.

Having trouble drawing an image in Qt using QGraphicsScene

The code below loads an image using QLabel. The code uses: myLabel.setMask(pixmap.mask()); and it works as it should. The problem comes when I try and load an image using QGraphicsScene.
#include <QApplication>
#include <QLabel>
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel myLabel;
QPixmap pixmap("/path/tomy/image.jpg");
myLabel.setPixmap(pixmap);
myLabel.setMask(pixmap.mask());
myLabel.show();
return app.exec();
}
In this code I am attempting to the same as above but using QGraphicsScene. The pixmap is loaded properly, after that I am not sure why the program is not working properly. Is it because there is no setMask() operation? Or is there an operation missing that is needed to make the image visible?
#include <QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtWidgets>
#else
#include <QtGui>
#endif
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPixmap pixmap("/path/tomy/image.jpg");
QGraphicsPixmapItem item( pixmap);
QGraphicsScene* scene = new QGraphicsScene;
scene->addItem(&item);
QGraphicsView view(scene);
view.show();
return a.exec();
}

QScrollArea contents not showing

Below I present a full Qt project in which I was expecting to see a label and a button showing in a scrollarea, but it seems I'm not expressing myself as Qt expects. What Qt expects?
project.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled13
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QHBoxLayout>
#include <QScrollArea>
#include <QLabel>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *mainLayout = new QHBoxLayout(this);
QScrollArea *scrollArea = new QScrollArea;
mainLayout->addWidget(scrollArea);
QWidget *widget = new QWidget;
scrollArea->setWidget(widget);
QHBoxLayout *hLayout = new QHBoxLayout;
widget->setLayout(hLayout);
QLabel *label = new QLabel("somelable");
hLayout->addWidget(label);
QPushButton *bt = new QPushButton("click");
hLayout->addWidget(bt);
}
Widget::~Widget()
{
}
In this specific code the problem is that you call
scrollArea->setWidget(widget);
before you add layout of the widget. Move the above mentioned call to the end of the constructor and you see the label and the button inside the scrollarea.
It's also mentioned in the QScrollArea::setWidget documentation:
Note that You must add the layout of widget before you call this
function; if you add it later, the widget will not be visible -
regardless of when you show() the scroll area.

How to play video by internet link with QT using QMediaPlayer object

I want to play video using QMediaplayer with internet link. I tried to do this by passing internet link to "setMedia" function but error occured:
"DirectShowPlayerService::doRender: Unresolved error code 80040218"
Example Code is:
#include "mainwindow.h"
#include <QApplication>
#include <QMediaPlayer>
#include <QVideoWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
QMediaPlayer * player = new QMediaPlayer;
QVideoWidget * vw = new QVideoWidget;
player->setVideoOutput(vw);
player->setMedia(QUrl("http://21.179.127.116/Katy%20Perry%20-%20Roar%20(Official).mp4"));
vw->setGeometry(100,100,300,400);
vw->show();
player->play();
qDebug()<<player->state();
return a.exec();
}
I am using Qt Creator 3.5.1 (enterprise)

Is it possible to implement SystemTrayIcon functionality in Qt Quick application

I am writing a QtQuick desktop application. I use both c++ (for functionality) and QML (for UI) in it.
I use QQuickView to show the interface written in QML.
I want this application to reside in System Tray when minimised.
I mean a functionality similar to this example. http://qt-project.org/doc/qt-4.8/desktop-systray.html .
I am trying to implement this feature but could not find a way to do this in my Qt Quick application.
Here is my main.cpp code:
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlFileSelector>
#include <QQuickView>
#include "myapp.h"
int main(int argc, char* argv[])
{
QGuiApplication app(argc,argv);
app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());
QDir::setCurrent(qApp->applicationDirPath());
MyApp myappObject;
QQuickView view;
view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));
view.rootContext()->setContextProperty("myappObject", &myappObject);
new QQmlFileSelector(view.engine(), &view);
view.setSource(QUrl("qrc:///myapp.qml"));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}
Please help by providing any hint/pointers to do this.
Thanks.
I was facing the same challenge today and ended up using the following solution within main(). Works great for me when using Qt 5.3. You should of course implement a better way to check whether the first root object is your application window object or not.
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QMessageBox>
#include <QAction>
#include <QMenu>
#include <QSystemTrayIcon>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
QMessageBox::critical(0, QObject::tr("Systray"),
QObject::tr("I couldn't detect any system tray "
"on this system."));
return 1;
}
QApplication::setQuitOnLastWindowClosed(false);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
QObject *root = 0;
if (engine.rootObjects().size() > 0)
{
root = engine.rootObjects().at(0);
QAction *minimizeAction = new QAction(QObject::tr("Mi&nimize"), root);
root->connect(minimizeAction, SIGNAL(triggered()), root, SLOT(hide()));
QAction *maximizeAction = new QAction(QObject::tr("Ma&ximize"), root);
root->connect(maximizeAction, SIGNAL(triggered()), root, SLOT(showMaximized()));
QAction *restoreAction = new QAction(QObject::tr("&Restore"), root);
root->connect(restoreAction, SIGNAL(triggered()), root, SLOT(showNormal()));
QAction *quitAction = new QAction(QObject::tr("&Quit"), root);
root->connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
QMenu *trayIconMenu = new QMenu();
trayIconMenu->addAction(minimizeAction);
trayIconMenu->addAction(maximizeAction);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
QSystemTrayIcon *trayIcon = new QSystemTrayIcon(root);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->setIcon(QIcon(":/resources/DatagnanLogoColor.png"));
trayIcon->show();
}
return app.exec();
}
Copy the Windos class (window.cpp/window.h) from systray example to your project, port it to Qt5 if necessary and open both from your main file:
int main(int argc, char* argv[])
{
// ...
QQuickView view;
// ...
view.show();
Window window;
window.show();
return app.exec();
}

Resources