2015-06-13 2 views
0

В начале я хочу извиниться за свой английский. Теперь перейдем к моей проблеме.Написание заставки с создателем Qt - показ предварительного просмотра в настройках заставки

Я пытаюсь написать экранную заставку с помощью Qt Creator (v5.0.1). Теперь у меня есть окно конфигурации (запущенное приложение с параметром «/ c»), полноэкранное окно (запущенное приложение с параметром «/ s»), и у меня нет окна предварительного просмотра (запуск приложения с параметрами «/ p» и «/ 1234567 ", где 1234567 - это дескриптор, и это может быть любое число. У меня есть проблема с правильным использованием этого дескриптора. Есть несколько примеров, которые я нашел, но все они не работают. Вот пример: Creating a Screen Saver for Windows . Я пытался скопировать этот код и заставить его работать на моей машине, но там было несколько проблем, некоторые из них я решил, но один я не могу Вот часть кода:..

QApplication app(argc, argv); 
QStringList arguments = app.arguments(); 

/* parse the commandline: 
* "[-/][Cc]" or no arguments for configuration mode 
* "[-/][Ss]", for fullscreen mode 
* "[-/][Pp][ :][0-9]+" for preview mode 
*/ 
Mode mode = ConfigurationMode; 
WId parent = 0; 
bool OK = arguments.size()<=1; 
for(int i=1;i<arguments.size();i++) 
{ 
    if(arguments[i].size()<2) 
     break; 
    switch(arguments[i][1].toLatin1()) 
    { 
    case 'c': case 'C': 
     mode = ConfigurationMode; 
     OK = true; 
     break; 

    case 's': case 'S': 
     mode = FullScreenMode; 
     OK = true; 
     break; 

    case 'p': case 'P': 
     if(arguments[i].size()>=4 && arguments[i][2]==':') 
      parent = (WId)arguments[i].mid(3).toUInt(&OK); 
     else if(arguments.size()>i) 
      parent = (WId)arguments[i+1].toUInt(&OK); 
     mode = PreviewMode; 
     break; 
    } 
} 

И далее - вторая часть кода:

ScreenSaverWidget* widget = new ScreenSaverWidget; 
widget->setAttribute(Qt::WA_DeleteOnClose); 
QObject::connect(widget, SIGNAL(destroyed()), &app, SLOT(quit())); 
switch(mode) 
{ 
case ConfigurationMode: 
    { 
     QSettings settings("QT", "Screen Saver"); 
     int animationSpeed = settings.value("animationSpeed", 10).toInt(); 
     //animationSpeed = QInputDialog::getInteger(0, "Configure Screen Saver", "Set Animation speed (0-100%)", animationSpeed, 0, 100); 
     animationSpeed = QInputDialog::getInt(0, "configure Screen Saver", "Set Animation speed (0-100%)",animationSpeed, 0, 100); 
     settings.setValue("animationSpeed", animationSpeed); 
    } 
    return 0; 

case FullScreenMode: 
    new ScreenSaverEventFilter(widget); 
    widget->showFullScreen(); 
    break; 

case PreviewMode: 
    { 
    widget->setWindowFlags(Qt::FramelessWindowHint|Qt::SubWindow); 
    ::SetParent(widget->winId(), parent);// <--- 
    RECT parentRect; 
    ::GetClientRect(parent, &parentRect);// <--- 
    widget->move(0,0); 
    widget->resize(parentRect.right, parentRect.bottom); 
    widget->show(); 
    } 
} 
return app.exec(); 

У меня есть три ошибки:

недопустимое преобразование из 'WID {ака неподписанных Int}' к 'HWND' [-fpermissive]

в две строки, которые отмечены во второй части код. Есть ли кто-нибудь, кто знает, как заставить его работать? Есть ли возможность сделать это с Qt? (дескриптор генерируется окном из окна.h, и я хочу установить его как родительский вид виджета Qt, возможно ли это?)

И еще один пример - сделать мой скринсейвер (в режиме предварительного просмотра) реагировать для ввода событий, например, события закрытия (из окна «Настройки экрана»), как это сделать?

EDIT 2015.06.14 -------------------------

Хорошо, я решил первую проблему, я добавил явное преобразование:

(...) 
    ::SetParent((HWND)widget->winId(), (HWND)parent);// <--- 
    RECT parentRect; 
    ::GetClientRect((HWND)parent, &parentRect);// <--- 
    (...) 

но теперь проблема в том, что мое приложение не реагирует на сигналы от экрана окна настройки экрана, например, (и это самое главное) он не закрывается, когда он должен - когда я выбираю другой экранной заставкой или когда я закрываю окно «Настройки заставки» (я должен убить процесс с помощью диспетчера задач). Есть ли кто-нибудь, кто знает и может написать здесь, как заставить мое приложение получать сигнал закрытия из окна настроек экрана?

ответ

0

Законный вызов установить один виджет как родитель для другого:

void QWidget::setParent(QWidget * parent)

Конечно, что необходимо для обеспечения правильного сигнала/обработки слота для такого вложенного виджета, и т.д. Я сам предпочел бы не использовать setParent вообще, но создайте родительский виджет QMainWindow с вложенным дочерним виджетами, который принимает весь родитель, используя вызов setCentralWidget, и тогда вам не нужно делать много ненужных вещей с размером и т. д. Но я не знаю всех деталей в вашей программе.

Устанавливает родительский элемент виджета родительскому объекту и сбрасывает флаги окна. Виджет перемещается в позицию (0, 0) в новом родителе. ... Примечание: виджет становится невидимым как часть изменения родительского элемента, даже если он был ранее видимым. Вы должны вызвать show(), чтобы виджет снова виден.

Что касается размеров и оконных флагов. Попробуйте, и если требуется изменить размер, вы, вероятно, можете сделать widget-> resize (parent-> size()). Что касается флагов, сначала попробуйте, не указав их. Существует некоторое сомнение в том, что эта комбинация применима к дочернему виджету внутри родителя.

В нашем порте приложения Windows я часто передаю winId() для HWND, но он работает, но помните, что это может избежать Действия в кармане Qt и всегда старайтесь сначала найти правильный Qt-способ. Что касается предупреждения компилятора для этого, вы можете использовать reinterpret_cast (widget-> winId()), если это так.

+0

Вы знаете, как использовать функцию: 'void QWidget :: setParent (QWidget * parent)' с типом аргументов WId? Я пробовал: 'WId parent = (WId) window_handle.toUInt(); widget.setParent ((QWidget *) parent); ' и он скомпилирован, но это не сработало. – Michal

+0

widget-> setParent (parent) должен так что вы хотите. Не забудьте вызвать widget-> show() и/или parent-> show() после. – AlexanderVX