Я хочу добавить текст в буфер обмена, а затем выйти из приложения сразу после добавления текста в буфер обмена.
QClipboard требуется для запуска в цикле событий, поэтому я создал QObject со слотом, который выполняетбуфер обмена скопировал для меня и вызвал слот с QTimer::singleShot
.Когда слот завершен, он издает сигнал от finished()
до QApplication::quit()
.
. Теперь проблема в том, что буфер обмена пуст, если я посылаю сигнал finished()
и вызывается QApplication::quit()
.Только когда я не завершаю QApplication, текст буфера обмена добавляется правильно.Почему это так?
Помимо QTimer :: singleShot, я также пытался вызвать свой слот с QMetaObject::invokeMethod
, но это тот же результат, что и выше.
main.cpp
#include "controller.h"
#include "worker.h"
#include <QApplication>
#include <QDebug>
#include <QTimer>
#include <QtGlobal>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
qDebug() << "Starting executing...\n";
QString bn = QString::fromStdString(argv[1]);
Worker b;
// QTimer::singleShot(1, [&] { b.onEventLoopStarted(bn); });
QMetaObject::invokeMethod(&b, "onEventLoopStarted", Qt::QueuedConnection, Q_ARG(QString, bn));
QObject::connect(&b, SIGNAL(finished()), &app, SLOT(quit()));
return app.exec();
}
worker.cpp
#include "worker.h"
#include <boost/format.hpp>
#include <cstdio>
#include <fstream>
#include <ios>
#include <iostream>
#include <QApplication>
#include <QClipboard>
#include <QDebug>
#include <QDir>
#include <QMessageBox>
#include <QtGui/QImage>
#include <QTimer>
#include <QThread>
#include <regex>
#include <stdio.h>
#include <stdlib.h>
#include <string>
// Worker::Worker(): bn("") {}
Worker::Worker(QObject *parent) : QObject(parent) {}
Worker::~Worker() {}
void Worker::set_bn(const QString &bn) {
this->bn = bn;
}
void Worker::doc_filename(std::string& fn) {
FILE *p;
char line [1024];
// https://stackoverflow.com/a/671528
p = popen("ps aux | grep '[/]usr/share/typora/Typora /'", "r");
if (!p) {
fprintf(stderr, "Error.");
exit(1);
}
while (fgets(line, sizeof(line) - 1, p)) {
std::string sline(line);
std::cout << "1 sline: " << sline << std::endl;
static const std::regex re("(.*\\/usr\\/share\\/typora\\/Typora)\\ (\\/.*)\n");
std::smatch m;
if(std::regex_match(sline, m, re)) {
fn = m[2];
std::cout << "2. path: " << fn << std::endl;
}
else {
std::cout << "2. not match" << std::endl;
}
}
pclose(p);
}
void Worker::onEventLoopStarted(QString bn) {
std::string fn = "";
this->doc_filename(fn);
if (fn == "") {
QMessageBox msgBox;
msgBox.setText("Open the typora document, where the image should be added to.");
msgBox.exec();
emit finished();
// QApplication::quit();
}
// from paramater get pwd and fn
// move fn to assets of fn
std::cout << "fn: " << fn << std::endl;
qDebug() << QDir::currentPath();
QString img_fn = QDir::cleanPath(QDir::currentPath() + QDir::separator() + bn);
qDebug() << "img_fn" << img_fn;
/* moves
std::ifstream in(img_fn, std::ios::in | std::ios::binary);
std::ofstream out(new_img_fn, std::ios::out | std::ios::binary);
out << in.rdbuf();
std::remove(img_fn);
*/
// Calculate img height, e.g. *0.8. use 0.8, then adjust after test
QImage img;
img.load(img_fn);
QString new_width = QString::number(img.width() * 0.8);
QString html_line = QString("<img src='%1' alt='' width='%2'>").arg(img_fn, new_width);
qDebug() << html_line;
// copy html_line to qt clipboard
QClipboard *clipboard = QApplication::clipboard();
clipboard->clear();
clipboard->setText(html_line);
qDebug() << "test";
//emit finished();
qDebug() << "finished Worker\n";
//QApplication::quit();
}
worker.h
#ifndef CHILD_OBJECT_H
#define CHILD_OBJECT_H
#include <QObject>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0);
~Worker();
void set_bn(const QString &bn);
void doc_filename(std::string&);
signals:
void finished();
public slots:
void onEventLoopStarted(QString);
private:
QString bn;
};
#endif // CHILD_OBJECT_H