Какое минимальное количество настроек требуется, чтобы QClipboard :: setText () работал под X11? - PullRequest
1 голос
/ 12 апреля 2009

После рекомендации uclip я обнаружил, что он не работает для копирования. Я начал отлаживать это, сначала преобразовав из QT3 в QT4, чтобы увидеть, если это помогло, но это не имело никакого значения, и в конце концов я обнаружил, что это знает ошибку , но помечена как "Не исправлю":

Это побочный эффект установки буфера обмена сразу после создания QApplication. Буфер обмена X11 основан на событиях и, как таковой, опирается на текущие метки времени с X-сервера. Эти временные метки автоматически обрабатывается QApplication. Однако в этом простом примере цикл обработки событий не запускается, поэтому мы не получаем обновленные метки времени с X-сервера, что в свою очередь заставляет QClipboard :: ownsClipboard () возвращать false. настройка буфер обмена в ответ, например, на событие клавиатуры или мыши делает это работать как положено.

Идеальный минимальный код для использования QClipboard :: setText () должен быть чем-то как следующее

#include <qapplication.h>
#include <qclipboard.h>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QClipboard *cb = QApplication::clipboard();
    QString input = "Hello clipboard";
    cb->setText(input);

    return 0;
    //return app.exec(); makes no difference from return 0
}

однако, как я уже сказал, это не сработает. Методом проб и ошибок у меня есть придумать следующее, что будет работать

#include <qapplication.h>
#include <qclipboard.h>
#include <QTimer>
#include <QtGui>
#include <iostream>

class MyApplication : public QApplication {
    Q_OBJECT
public:
    MyApplication(int & argc, char ** argv) : QApplication(argc, argv)
    {
    }
public slots:
    void setClipboard()
    {
        QClipboard *cb = QApplication::clipboard();
        QString input = "THIS WORKS";
        std::cout << "setText line " << __LINE__+1 << "\n";
        cb->setText(input);
    }
};

class MainWidget:public QMainWindow {
public:
    MainWidget() {
        QClipboard *clipboard = QApplication::clipboard();
        std::cout << "setText line " << __LINE__+1 << "\n";
        clipboard->setText("This will not be copied to the clipboard, apparently also too early");
    }
};


int main(int argc, char *argv[])
{
    MyApplication app(argc, argv);

    QClipboard *cb = QApplication::clipboard();
    QString input = "This will not be copied to the clipboard, too early";
    std::cout << "setText line " << __LINE__+1 << "\n";
    cb->setText(input);

    //QTimer::singleShot(3, &app, SLOT(setClipboard())); // 3 ok, 2 not ok

    MainWidget mainWid;
    //mainWid.show();

    QTimer::singleShot(2, &app, SLOT(setClipboard())); // 2 ok, 1 not ok

    return app.exec();
}
#include "main.moc"

Однако я уверен, что это не минимальный и не лучший способ сделать это. Итак, поэтому я спрашиваю, что потребуется для генерации такого необходимого X11 обновление отметки времени с минимальными усилиями и воздействием?

Ответы [ 2 ]

0 голосов
/ 28 августа 2009

Полагаю, вам не повезло на X11. Управление приложением буфера обмена X11 зависит от самого приложения. Поэтому, когда ваше приложение закрывается, данные в буфере обмена теряются.

Думаю, вам лучше всего позвонить в командную строку xclip. Вставьте в него нужный вам текст из буфера обмена. Я не уверен, насколько обычно доступна эта команда. И он должен делать что-то, что может быть воссоздано с кодом более низкого уровня x?

0 голосов
/ 12 апреля 2009

Я бы попробовал что-то вроде:

QApplication app(argc, argv);
// Paste something to your clipboard
app.processEvents();

Это фактически делает цикл обработки событий приложения Qt всеми ожидающими событиями чем-то, чего не происходит, если вы не вызываете app.exec (), как в первом примере, и очень похоже на то, что вы делаете во втором Во-первых, вы делаете что-то эквивалентное с таймером. Я не пробовал, хотя, и это также далеко от того, что предлагает документация (обрабатывать буфер обмена как ответ на события пользовательского ввода).

...