2009-04-12 5 views
0

После рекомендации uclip Я узнал, что он не работает для копирования. я начал отладки этого первое преобразование из QT3 на Qt4, чтобы убедиться, что помогло, но это не имеет никакого значения, и в конце концов я обнаружил, что является know bug, но помечено как «не исправят»:Какова минимальная сумма настройки, необходимая для работы QClipboard :: setText() для работы в X11?

Это побочный эффект установки буфера обмена сразу после создания 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 с минимальными усилиями и воздействием?

ответ

0

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

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

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

+0

К сожалению, это не помогает, потому что app.processEvents() запускает обработку событий QT, которая зависит от некоторой активности X11, которая не запускается. Первоначально я использовал «return app.exec()» вместо «return 0» в простом примере. – hlovdal

+0

Итак, какой цикл событий X11 должен быть запущен, чтобы буфер обмена работал? Не могу придумать что-либо на стороне Qt. –

+0

Да, возможно, это скорее вопрос X11, чем вопрос QT. Создание экземпляра MainWidget, по-видимому, достаточно, но я хотел бы избежать создания более тяжелого фиктивного объекта, чем это необходимо, и, если это возможно, также избегать создания фиктивных объектов. – hlovdal

0

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

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