Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: #pragma от Декабря 03, 2009, 13:38



Название: [решено]Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 03, 2009, 13:38
Я пытаюсь сделать простой эмулятор терминала(только текст в режиме ввод-вывод) и мне посоветовали использовать класс QPlainTextEdit в этой теме (http://www.prog.org.ru/index.php?topic=11516). Возникла такая проблема: когда окно активно и вывод закончен,нужно по нажатию любой клавиши закрывать его. Я так понимаю нужно делать свой сигнал для этого. В этом классе нет никаких сигналов,связанных с состоянием активности окна,и есть один для нажатия на кнопки,но там только Pg-Up,-Down,Right и Left. Можно ли сделать такой сигнал? Каким образом?
Я читал,как делать сигналы,но в том примере подразумевалось существование сигнала clicked(),он был связан со слотом,в котором было слово emit и самодельный сигнал,который далее связывался с другими слотами с помощью connect. Здесь ситуация немного другая.


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: spectre71 от Декабря 03, 2009, 14:49
Я пытаюсь сделать простой эмулятор терминала(только текст в режиме ввод-вывод) и мне посоветовали использовать класс QPlainTextEdit в этой теме (http://www.prog.org.ru/index.php?topic=11516). Возникла такая проблема: когда окно активно и вывод закончен,нужно по нажатию любой клавиши закрывать его. Я так понимаю нужно делать свой сигнал для этого. В этом классе нет никаких сигналов,связанных с состоянием активности окна,и есть один для нажатия на кнопки,но там только Pg-Up,-Down,Right и Left. Можно ли сделать такой сигнал? Каким образом?
Я читал,как делать сигналы,но в том примере подразумевалось существование сигнала clicked(),он был связан со слотом,в котором было слово emit и самодельный сигнал,который далее связывался с другими слотами с помощью connect. Здесь ситуация немного другая.

virtual void QWidget::keyPressEvent ( QKeyEvent * event )


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 03, 2009, 16:38
А можете поподробней немного разъяснить,а то непонятно,что вообще делать. Я разбираюсь медленно,пишу,пока понятно,что пишу,хотя бы примерно. Тут я немного застрял. Как связаны между собой два этих класса?


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: spectre71 от Декабря 03, 2009, 16:42
А можете поподробней немного разъяснить,а то непонятно,что вообще делать. Я разбираюсь медленно,пишу,пока понятно,что пишу,хотя бы примерно. Тут я немного застрял. Как связаны между собой два этих класса?

Загляни  в Assistant!

QPlainTextEdit Inherits QAbstractScrollArea Inherits QFrame Inherits QWidget.


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 03, 2009, 17:32
Вот я что-то сделал,но неуверен,правильно ли,так как недопонимаю материал. Я переопределил этот метод,и теперь его можно сделать public и использовать connect за пределами реализации класса?
Код
C++ (Qt)
#include "terminal.h"
/* -------------------------------------------------------------------------- */
 QTerminal::QTerminal () :QPlainTextEdit()
 {
    setGeometry( 20, 20, 640, 480 );
    setWordWrapMode( QTextOption::WrapAnywhere );
    setPalette ( QPalette( QBrush(QColor(0x00,0x00,0x00)), // windowText
                           QBrush(QColor(0xff,0xff,0xff)), // button
                           QBrush(QColor(0xff,0xff,0xff)), // light
                           QBrush(QColor(0xff,0xff,0xff)), // dark
                           QBrush(QColor(0xff,0xff,0xff)), // mid
                           QBrush(QColor(0xff,0xff,0xff)), // text
                           QBrush(QColor(0xff,0xff,0xff)), // bright_text
                           QBrush(QColor(0x00,0x00,0x00)), // base
                           QBrush(QColor(0x00,0x00,0x00))  // window
                         ));
    setVerticalScrollBarPolicy   ( Qt::ScrollBarAlwaysOff );
    setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
    setReadOnly ( true );
    QObject::connect(this, SIGNAL( is_active (QKeyEvent *)     ),
                     this, SLOT  ( keyPressEvent (QKeyEvent *) ) );
 
    QObject::connect(this, SIGNAL( is_active (QKeyEvent *)     ),
                     this, SLOT  ( keyPressEvent (QKeyEvent *) ) );
 }
/* -------------------------------------------------------------------------- */
 void QTerminal::keyPressEvent ( QKeyEvent * event )
 {
    if (isActiveWindow())
    {
       emit is_active ( event );
    }
 }
/* -------------------------------------------------------------------------- */
Это правильно?


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: spectre71 от Декабря 03, 2009, 18:38
Вот я что-то сделал,но неуверен,правильно ли,так как недопонимаю материал. Я переопределил этот метод,и теперь его можно сделать public и использовать connect за пределами реализации класса?
Код
C++ (Qt)
...
Это правильно?

Нет конечно!

Это просто ерунда
     QObject::connect(this, SIGNAL( is_active (QKeyEvent *)     ),
                      this, SLOT  ( keyPressEvent (QKeyEvent *) ) );
 
     QObject::connect(this, SIGNAL( is_active (QKeyEvent *)     ),
                      this, SLOT  ( keyPressEvent (QKeyEvent *) ) );



Код
C++ (Qt)
#include "terminal.h"
/* -------------------------------------------------------------------------- */
 QTerminal::QTerminal () :QPlainTextEdit()
 {
    setGeometry( 20, 20, 640, 480 );
    setWordWrapMode( QTextOption::WrapAnywhere );
    setPalette ( QPalette( QBrush(QColor(0x00,0x00,0x00)), // windowText
                           QBrush(QColor(0xff,0xff,0xff)), // button
                           QBrush(QColor(0xff,0xff,0xff)), // light
                           QBrush(QColor(0xff,0xff,0xff)), // dark
                           QBrush(QColor(0xff,0xff,0xff)), // mid
                           QBrush(QColor(0xff,0xff,0xff)), // text
                           QBrush(QColor(0xff,0xff,0xff)), // bright_text
                           QBrush(QColor(0x00,0x00,0x00)), // base
                           QBrush(QColor(0x00,0x00,0x00))  // window
                         ));
    setVerticalScrollBarPolicy   ( Qt::ScrollBarAlwaysOff );
    setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
    setReadOnly ( true );
 }
/* -------------------------------------------------------------------------- */
 void QTerminal::keyPressEvent ( QKeyEvent * event )
 {
     // Do something
 }
/* -------------------------------------------------------------------------- */
 


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: Igors от Декабря 03, 2009, 18:51
Вот я что-то сделал,но неуверен,правильно ли,так как недопонимаю материал. Я переопределил этот метод,и теперь его можно сделать public и использовать connect за пределами реализации класса?
Есть ли Вас необходимость (или выгода) использовать сигнал/слот? Я лично не вижу здесь таковой. Ну и перекрывайте спокойно keyPressEvent как Spectre сказал. Пользоваться сигнал/слот никто не заставляет. А если хотите изучать - посвязывайте сначала готовые сигналы с готовыми слотами (они очень удобно расставлены). Имя QTerminal лучше заменить чтобы было ясно: это не Qt класс.


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 03, 2009, 19:35
Есть ли Вас необходимость (или выгода) использовать сигнал/слот? Я лично не вижу здесь таковой. Ну и перекрывайте спокойно keyPressEvent как Spectre сказал. Пользоваться сигнал/слот никто не заставляет. А если хотите изучать - посвязывайте сначала готовые сигналы с готовыми слотами (они очень удобно расставлены). Имя QTerminal лучше заменить чтобы было ясно: это не Qt класс.
Дело в том,что я вызываю консольное приложение с помощю QProcess в том GUI,который пытаюсь сделать.Вывод программы нужно вывести на терминал. Выглядит всё это так
Код
C++ (Qt)
/* -------------------------------------------------------------------------- */
 void MainWindow::readOut()
 {
    terminal->insertPlainText (
                       QString ( interpreter->readAllStandardOutput().data()));
    terminal->show();
 }
/* -------------------------------------------------------------------------- */
 void MainWindow::run()
 {
 #ifdef _UNIX_
   interpreter->start("./interpreter",QStringList() << *args << filename);
 #endif
 #ifdef _WINDOWS_
   // ...
 #endif
 }
/* -------------------------------------------------------------------------- */
 void MainWindow::createConnections()
 {
    connect(interpreter, SIGNAL(readyReadStandardError()),this,
                                                              SLOT(readErr()));
 
    connect(interpreter, SIGNAL(readyReadStandardOutput()),this,
                                                              SLOT(readOut()));
 }
/* -------------------------------------------------------------------------- */
Когда консольная программа завершает работу,нужно узнать,активно ли окно терминала,и если да,то при нажатии любой клавиши закрыть терминал.Что в этом случае можно ещё использовать кроме сигналов?


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: spectre71 от Декабря 03, 2009, 19:53
Что в этом случае можно ещё использовать кроме сигналов?

Тебе уже написали, ты хоть бы посмотрел в доке:
virtual void QWidget::keyPressEvent ( QKeyEvent * event )
Кроме сигналов есть еще и события

Код
C++ (Qt)
 void QTerminal::keyPressEvent ( QKeyEvent * event )
 {
     // Do something
 }


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: Igors от Декабря 03, 2009, 20:03
Когда консольная программа завершает работу,нужно узнать,активно ли окно терминала,и если да,то при нажатии любой клавиши закрыть терминал.Что в этом случае можно ещё использовать кроме сигналов?
Код
C++ (Qt)
 void MainWindow::createConnections()
 {
    connect(interpreter, SIGNAL(readyReadStandardError()),this,
                                                              SLOT(readErr()));
 
    connect(interpreter, SIGNAL(readyReadStandardOutput()),this,
                                                              SLOT(readOut()));
// садимся на finished
    connect(interpreter, SIGNAL(finished(int, QProcess::ExitCode)),this,
                                                              SLOT(doneInter()));
 }
 
void MainWindow::doneInter()
{
// уходим если до консоли дело не дошло
   if (terminal->isVisible()) QApplication::quit();
   else terminal->mDoneFlag = true;
}
 
void QTerminal::keyPressEvent ( QKeyEvent * event )
{
// уходим если нажат anyKey
    if (mDoneFlag) QApplication::quit();
}
 


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 03, 2009, 20:12
Так значит, функцию void QTerminal::keyPressEvent ( QKeyEvent * event ) вызывать не нужно нигде и связывать тоже.. Так уже понятнее,спасибо за помощь!


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: spectre71 от Декабря 03, 2009, 20:18
Так значит, функцию void QTerminal::keyPressEvent ( QKeyEvent * event ) вызывать не нужно нигде и связывать тоже.. Так уже понятнее,спасибо за помощь!


Это виртульный метод класса-предка, он не имеет никакого отношения к механизму сигналов/слотов.
Много чего можно сделать переопределив  виртульные методы. :)
Всегда смотри что есть у классов-предков.


Название: Re: Как сделать сигнал для класса,происходящего от QPlainTextEdit?
Отправлено: #pragma от Декабря 04, 2009, 13:48
Что-то не получается никак.Блин,я не могу никак въехать в эту концепцию сигналов/слотов/событий. Как оно вообще работает?
Как закрыть этот терминал(и только его) при окончании работы консольной проги? Пока всё это похоже на какое-то шаманство с бубном. Я бы уже давно написал,если бы вживую поглядеть пример. В документации же одна писанина про то что это такое,но ни слова,как это использовать. Что с этим виртуальным методом делать-то? :)

P.S.Наконец-то что-то получилось! Спасибо,что не стали за меня писать код,и я разобрался сам (ну кое-как правда). :)