I am trying to migrate my code from QWebView to QWebEngine. I want to add an object from my code into the javascript. In QWebView it was possible with the function addToJavaScriptWindowObject. How can we do this in QWebEngine.
webview->page()->mainFrame()->addToJavaScriptWindowObject("qtObject", this);
Our java script need to call functions of "qtObject".
QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
if (!webChannelJsFile.open(QIODevice::ReadOnly)) {
qDebug() << QString("Couldn't open qwebchannel.js file: %1").arg(webChannelJsFile.errorString());
}
else {
qDebug() << "OK webEngineProfile";
QByteArray webChannelJs = webChannelJsFile.readAll();
webChannelJs.append(
"\n"
"var qtObject"
"\n"
"new QWebChannel(qt.webChannelTransport, function(channel) {"
" qtObject = channel.objects.qtObject;"
"});"
);
QWebEngineScript script;
script.setName("qwebchannel.js");
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setRunsOnSubFrames(false);
script.setWorldId(QWebEngineScript::MainWorld);
script.setSourceCode(webChannelJs);
page->scripts().insert(script);
QWebChannel *channel = new QWebChannel(page);
channel->registerObject("qtObject", this);
page->setWebChannel(channel);
return page;
Related
So I wrote a Qt quick application that takes user inputs and stores them in a json file. I now want to add a feature that lets me recall the data in my file and display it in a text field within my application. I can get the text in the C++ portion of my application, Im just not sure how to display it in my user interface. Here is the code to get the text from my json file.
void Jsonfile:: display(){
//1. Open the QFile and write it to a byteArray and close the file
QFile file;
file.setFileName("data.json");
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "file couldn't be opened/found";
return;
}
QByteArray byteArray;
byteArray = file.readAll();
file.close();
//2. Format the content of the byteArray as QJsonDocument
//and check on parse Errors
QJsonParseError parseError;
QJsonDocument jsonDoc;
jsonDoc = QJsonDocument::fromJson(byteArray, &parseError);
if(parseError.error != QJsonParseError::NoError){
qWarning() << "Parse error at " << parseError.offset << ":" << parseError.errorString();
return;
}
QTextStream textStream(stdout);
textStream << jsonDoc.toJson(QJsonDocument::Indented);
}
I'm using the wonderful [QtAV](https://github.com/wang-bin/QtAV/) package to perform video decoding. What I want to achieve is to obtain a thumbnail for a video. Here is what I have done so far.
bool saveThumb( QString videoFile ) {
AVDemuxer *demux = new AVDemuxer();
demux->setSeekUnit( SeekByFrame );
demux->setSeekType( KeyFrameSeek );
VideoDecoder *vdec = VideoDecoder::create( VideoDecoderId_FFmpeg );
demux->setMedia( videoFile );
qDebug() << "Loading file:" << demux->load();
qDebug() << "Seeking to 50%" << demux->seek( 0.5 );
qDebug() << "Reading frame:" << demux->readFrame();
vdec->setCodecContext( demux->videoCodecContext() );
vdec->open();
Packet pkt = demux->packet();
qDebug() << "Packet valid:" << pkt.isValid();
qDebug() << "Decoding packet:" << vdec->decode( pkt );
VideoFrame frame = vdec->frame();
qDebug() << "Valid frame:" << frame.isValid();
QImage img = frame.toImage();
qDebug() << "Valid image:" << ( not img.isNull() );
bool saved = img.save( videoFile + ".jpg" );
return saved;
}
My problem is that frame.isValid() always returns false, no matter to where I seek, or which video I play. All the checks above return true.
I would like to add that if I use AVPlayer and play the video, the video renders properly, however there is no audio playing.
Also I am able to capture snapshots using AVPlayer::videoCapture()->capture()
For the record, I have tried this using both Qt4 and Qt5
For getting thumbnails of videos you can simply use QtAV VideoFrameExtractor class like:
#include "QtAV/VideoFrameExtractor.h"
...
bool saveThumb(const QString& videoFile) {
auto extractor = new QtAV::VideoFrameExtractor;
connect(
extractor,
&QtAV::VideoFrameExtractor::frameExtracted,
extractor,
[this, extractor, videoFile](const QtAV::VideoFrame& frame) {
const auto& img = frame.toImage();
auto saved = img.save(videoFile + ".jpg" );
extractor->deleteLater();
});
connect(
extractor,
&QtAV::VideoFrameExtractor::error,
extractor,
[this, extractor](const QString& errorStr) {
qDebug() << errorStr;
extractor->deleteLater();
});
extractor->setAsync(true);
extractor->setSource(videoFile);
extractor->setPosition(1);
}
I load all text files from my folder to the MainMenu in my Qt application.
void MainWindow::loadFilesToMainMenu() {
QString pathToDir("/myfiles");
QDirIterator it(pathToDir, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString curPathName = it.next();
QStringList fileSegments = curPathName.split('/');
QString curFileName = fileSegments.at(fileSegments.size() - 1);
QAction* action = new QAction(tr(curFileName.toStdString().c_str()), this);
action->setStatusTip(tr(curPathName.toStdString().c_str()));
ui->menuFileList->addAction(action);
// if new style selected?
connect(action, SIGNAL(triggered()), this, SLOT(onLoadFile()));
}
}
There I create QActions for all files in my folder 'myfiles' and I connect these each of these ations to the SLOT onLoadfile():
void MainWindow::onLoadFile() {
QAction *action = qobject_cast<QAction *>(sender());
if (action)
{
qDebug() << " onLoadFile " << action->data().toString();
}
}
So each time I select one of those files in my MainMenu, this SLOt is triggered, but my debug message says:
onLoadFile ""
When I for instance select /myfiles/file1.txt
onLoadFile "/myfiles/file1.txt"
Wham am I missing? Thanx in advance
The answer from #m.s. solves my question very well...
You should use QAction::setData() before trying to read the data – m.s
I have multiples DNS record (MX, CNAME , TXT) and I would like to read the TXT record content.
The lookup() function never emit finished(), I am using this code to test:
QDnsLookup m_dns = new QDnsLookup(this);
connect(m_dns, SIGNAL(finished()), this, SLOT(onHandle()));
m_dns->setType(QDnsLookup::TXT);
m_dns->setName("uol.com.br");
m_dns->lookup();
void Update::onHandle()
{
if (m_dns->error() != QDnsLookup::NoError)
qDebug() << m_dns->error() << m_dns->errorString();
foreach (const QDnsServiceRecord &record, m_dns->serviceRecords())
qDebug() << "Name: " << record.name();
emit handled();
}
If I use a online service to read the record, it works!
The onHandle slot should be looking at m_dns->textRecords(), not m_dns->serviceRecords().
The correct code:
foreach (const QDnsTextRecord &record , m_dns->textRecords()) {
qDebug() << "Values: " << record.values();
qDebug() << "Name: " << record.name();
}
I am trying to run code of copying files in other thread so that it may not freeze the GUI of the application.
I found that it does not seem to work in a separate thread.
Why is it not working ?
void CopyOperation::run()
{
CopyFilesToFolder(list,sFolder);
}
bool CopyOperation::CopyFilesToFolder(const QStringList &oFileList,const QString
&sTargetFolder)
{
if(sTargetFolder.isEmpty())
{
status = false;
return false;
}
QDir dir(sTargetFolder);
if(!dir.exists()) dir.mkdir(sTargetFolder);
QString sOldDirPath = dir.currentPath();
//if(!dir.setCurrent(sTargetFolder)) return false;
QFile file;
status = true;
foreach(QString sFileName,oFileList)
{
file.setFileName(sFileName);
QFileInfo info(sFileName);
QString newfile = sTargetFolder + "/" + info.fileName();
qDebug() << "\n name = " << newfile;
if(!QFile::copy(sFileName,newfile))
//if(!file.copy(newfile))
{
qDebug() << "\n File copy failed .. " + file.fileName() + " Error : " + file.errorString();
status = false;
break;
}
}
qDebug() << "\n Result .. " << file.errorString() << "code " << file.error();
//dir.setCurrent(sOldDirPath);
return status;
}
Since you didn't post code, I just can try to guess what is the problem. Qt has a static function:
bool copy ( const QString & fileName, const QString & newName )
There is also a copy which is not static:
bool copy ( const QString & newName )
Both of them will fail if file defined by newName already exists, ie. existing file will not be overwritten. Also, maybe path doesn't exists. Without some portion of code is difficult to guess what is the problem.