Russian Qt Forum
Ноябрь 07, 2024, 00:42 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [решено]Как сделать сигнал для класса,происходящего от QPlainTextEdit?  (Прочитано 6188 раз)
#pragma
Гость
« : Декабрь 03, 2009, 13:38 »

Я пытаюсь сделать простой эмулятор терминала(только текст в режиме ввод-вывод) и мне посоветовали использовать класс QPlainTextEdit в этой теме. Возникла такая проблема: когда окно активно и вывод закончен,нужно по нажатию любой клавиши закрывать его. Я так понимаю нужно делать свой сигнал для этого. В этом классе нет никаких сигналов,связанных с состоянием активности окна,и есть один для нажатия на кнопки,но там только Pg-Up,-Down,Right и Left. Можно ли сделать такой сигнал? Каким образом?
Я читал,как делать сигналы,но в том примере подразумевалось существование сигнала clicked(),он был связан со слотом,в котором было слово emit и самодельный сигнал,который далее связывался с другими слотами с помощью connect. Здесь ситуация немного другая.
« Последнее редактирование: Декабрь 05, 2009, 16:23 от #pragma » Записан
spectre71
Гость
« Ответ #1 : Декабрь 03, 2009, 14:49 »

Я пытаюсь сделать простой эмулятор терминала(только текст в режиме ввод-вывод) и мне посоветовали использовать класс QPlainTextEdit в этой теме. Возникла такая проблема: когда окно активно и вывод закончен,нужно по нажатию любой клавиши закрывать его. Я так понимаю нужно делать свой сигнал для этого. В этом классе нет никаких сигналов,связанных с состоянием активности окна,и есть один для нажатия на кнопки,но там только Pg-Up,-Down,Right и Left. Можно ли сделать такой сигнал? Каким образом?
Я читал,как делать сигналы,но в том примере подразумевалось существование сигнала clicked(),он был связан со слотом,в котором было слово emit и самодельный сигнал,который далее связывался с другими слотами с помощью connect. Здесь ситуация немного другая.

virtual void QWidget::keyPressEvent ( QKeyEvent * event )
Записан
#pragma
Гость
« Ответ #2 : Декабрь 03, 2009, 16:38 »

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

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

Загляни  в Assistant!

QPlainTextEdit Inherits QAbstractScrollArea Inherits QFrame Inherits QWidget.
Записан
#pragma
Гость
« Ответ #4 : Декабрь 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 );
    }
 }
/* -------------------------------------------------------------------------- */
Это правильно?
Записан
spectre71
Гость
« Ответ #5 : Декабрь 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
 }
/* -------------------------------------------------------------------------- */
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Декабрь 03, 2009, 18:51 »

Вот я что-то сделал,но неуверен,правильно ли,так как недопонимаю материал. Я переопределил этот метод,и теперь его можно сделать public и использовать connect за пределами реализации класса?
Есть ли Вас необходимость (или выгода) использовать сигнал/слот? Я лично не вижу здесь таковой. Ну и перекрывайте спокойно keyPressEvent как Spectre сказал. Пользоваться сигнал/слот никто не заставляет. А если хотите изучать - посвязывайте сначала готовые сигналы с готовыми слотами (они очень удобно расставлены). Имя QTerminal лучше заменить чтобы было ясно: это не Qt класс.
Записан
#pragma
Гость
« Ответ #7 : Декабрь 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()));
 }
/* -------------------------------------------------------------------------- */
Когда консольная программа завершает работу,нужно узнать,активно ли окно терминала,и если да,то при нажатии любой клавиши закрыть терминал.Что в этом случае можно ещё использовать кроме сигналов?
Записан
spectre71
Гость
« Ответ #8 : Декабрь 03, 2009, 19:53 »

Что в этом случае можно ещё использовать кроме сигналов?

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

Код
C++ (Qt)
 void QTerminal::keyPressEvent ( QKeyEvent * event )
 {
     // Do something
 }
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Декабрь 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();
}
 
Записан
#pragma
Гость
« Ответ #10 : Декабрь 03, 2009, 20:12 »

Так значит, функцию void QTerminal::keyPressEvent ( QKeyEvent * event ) вызывать не нужно нигде и связывать тоже.. Так уже понятнее,спасибо за помощь!
Записан
spectre71
Гость
« Ответ #11 : Декабрь 03, 2009, 20:18 »

Так значит, функцию void QTerminal::keyPressEvent ( QKeyEvent * event ) вызывать не нужно нигде и связывать тоже.. Так уже понятнее,спасибо за помощь!


Это виртульный метод класса-предка, он не имеет никакого отношения к механизму сигналов/слотов.
Много чего можно сделать переопределив  виртульные методы. Улыбающийся
Всегда смотри что есть у классов-предков.
Записан
#pragma
Гость
« Ответ #12 : Декабрь 04, 2009, 13:48 »

Что-то не получается никак.Блин,я не могу никак въехать в эту концепцию сигналов/слотов/событий. Как оно вообще работает?
Как закрыть этот терминал(и только его) при окончании работы консольной проги? Пока всё это похоже на какое-то шаманство с бубном. Я бы уже давно написал,если бы вживую поглядеть пример. В документации же одна писанина про то что это такое,но ни слова,как это использовать. Что с этим виртуальным методом делать-то? Улыбающийся

P.S.Наконец-то что-то получилось! Спасибо,что не стали за меня писать код,и я разобрался сам (ну кое-как правда). Улыбающийся
« Последнее редактирование: Декабрь 05, 2009, 16:22 от #pragma » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.165 секунд. Запросов: 23.