LINUX.ORG.RU

Повторный вызов или создание окна

 , , ,


0

1

Разрабатывается оконное приложение на QT5, которое работает на raspberry PI в консольном режиме.

По определенному событию необходимо вывести на экран форму, по определенному событию её же нужно убрать. Я вижу два варианта решения этой проблемы:

1. Единожды создать объект, после чего методами show и hide выводить и убирать окно.

2. Постоянно создавать и уничтожать объект.

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

main.cpp

ServiceWindow *my = new ServiceWindow(a.desktop());

Delegate *myDelegate = new Delegate();

QObject::connect(myDelegate, SIGNAL(haveOperator(int)), my, SLOT(show()));
QObject::connect(myDelegate, SIGNAL(dontHaveOperator(bool)), my, SLOT(hide()));

servicewindow.h

namespace Ui {
class ServiceWindow;
}

class ServiceWindow : public QWidget
{
    Q_OBJECT

public:
    explicit ServiceWindow(QWidget *parent = 0);
    ~ServiceWindow();

public slots:

protected:
    void closeEvent(QCloseEvent *event);
    void showEvent(QShowEvent *event);
//    bool event(QEvent *myEvent);

private slots:
    void timeIter();

private:
    Ui::ServiceWindow *ui;
    QTime mytime;
    QTime mytime_s;
    QTimer *time1;
};

servicewindow.cpp

ServiceWindow::ServiceWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ServiceWindow)
{
    ui->setupUi(this);

    time1 = new QTimer();
    time1->setInterval(1000);
    connect(time1, SIGNAL(timeout()), this, SLOT(timeIter()));

}

ServiceWindow::~ServiceWindow()
{
    delete ui;
}


void ServiceWindow::timeIter() {
    mytime_s = mytime_s.addSecs(1);
    ui->labelTimer->setText(mytime_s.toString());
    time1->start();
}

void ServiceWindow::closeEvent(QCloseEvent *event){
    qDebug() << "Помолясь, начнем";
    mytime_s.setHMS(0, 0, 0);
    ui->labelTimer->setText(mytime_s.toString());
    time1->stop();
    this->clearMask();
    event->accept();
    qDebug() << this->isHidden();
}

void ServiceWindow::showEvent(QShowEvent *event){
    time1->start();
    mytime = QTime::currentTime();
    mytime_s.setHMS(0, 0, 0);
    event->accept();

    ui->labelStart->setText(mytime.toString());
}

Если идти вторым путем, то после уничтожения объекта окно исчезает, но при повторном создании объекта происходит следующее: создается новый экземпляр класса, но форма на экран не выводится.

main.cpp

Delegate *myDelegate = new Delegate();

QObject::connect(myDelegate, SIGNAL(haveOperator(int)), myDelegate, SLOT(serviceMonitorShow()));
QObject::connect(myDelegate, SIGNAL(dontHaveOperator(bool)), myDelegate, SLOT(serviceMonitorHide()));

Слоты serviceMonitorShow() и serviceMonitorHide().

void Delegate::serviceWindowShow(){
    qDebug() << myServiceWindow;
    if(myServiceWindow == 0) myServiceWindow = new ServiceWindow();
    myServiceWindow->show();
    qDebug() << myServiceWindow->isEnabled() << myServiceWindow->isVisible();
}

void Delegate::serviceWindowHide(){
    myServiceWindow->close();
    delete myServiceWindow;
    myServiceWindow = 0;
}

В какую сторону копать?


Разрабатывается оконное приложение на QT5, которое работает на raspberry PI в консольном режиме.

Тебе не кажется, что это взаимоисключающие понятия? Ну, либо поясни конкретнее чего ты хочешь.

Предположение: ты хочешь на самом деле 2 приложения - одно консольное выполняющее некую задачу, и второе десктопное, висящее постоянно в фоне, и отображающее окно(окна) по запросу первого. Соответственно тебе надо посмотреть в сторону IPC, в данном случае DBus должен подойти хорошо (в Qt были средства для работы с ним, если еще не выпилили).

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

Я не вполне корректно выразился. Есть raspberry pi, которая работает без гуев. Есть приложение, которое в штатном режиме тоже работает без гуев, но время от времени выводить форму на монитор. Так яснее?

chehov
() автор топика
Ответ на: комментарий от chehov

Есть приложение, которое в штатном режиме тоже работает без гуев, но время от времени выводить форму на монитор. Так яснее?

Ты, наверное, когда тебе надо вывести форму на монитор, забываешь запустить event loop, т.е. вызвать app.exec().

Хотя я бы, на твоем месте, делал приложение из 2 кусков: морда и консольная часть, и «дружил» бы их через DBus.

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

Хотя я бы, на твоем месте, делал приложение из 2 кусков: морда и консольная часть, и «дружил» бы их через DBus.

+1, так и надо делать

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от Sectoid

Или если там не нужно постоянно что-то гонять, то через сетевые сокеты. Пример: MPD.

zinfandel ★★
()
Ответ на: комментарий от Sectoid

App.exec() запускаю.

Решение было принято следующее: вместо того, чтобы показывать/убирать форму решили убирать контролы, а вместо них показывать логотип компании.

Про DBus погуглю в ближайшее время. Единственное что, мне бы очень хотелось понять почему форма так себя вела.

chehov
() автор топика
Ответ на: комментарий от chehov

Единственное что, мне бы очень хотелось понять почему форма так себя вела.

Я бы сказал, что это баг сборки Qt5 под raspberry. У меня с Qt4 и платкой на арме, в которую зашит emdebian, через фреймбуфер все прекрасно отображается. Формы по show/hide ведут себя корректно.

solovey ★★
()

Разобрался с проблемой. В qt5 есть такой механизм - QPA - абстракция платформы. Суть в том, что у меня qt5 был скомпилирован с платформой по умолчанию - eglfs. Запуск приложений из-под иксов и с параметром --platform xcb полностью решает проблему. Всем спасибо.

chehov
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.