Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Qt. Duda sobre promoted widgets

Estas en el tema de Qt. Duda sobre promoted widgets en el foro de C/C++ en Foros del Web. Bueno, después de mas de un mes sin tener oportunidad de retomar Qt, ahora toca preguntar una duda. Es una duda un poco tonta, pero ...
  #1 (permalink)  
Antiguo 15/02/2015, 10:12
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Qt. Duda sobre promoted widgets

Bueno, después de mas de un mes sin tener oportunidad de retomar Qt, ahora toca preguntar una duda.

Es una duda un poco tonta, pero es por aclarar un concepto que no termino de ver.

La duda es: ¿cual es la diferencia entre crear una clase heredándola de otra con código, a crear un widget en el Designer y por medio de la opción "promote to..." personalizarle sus propiedades?...(si es que hay alguna)

Gracias
__________________
Mi calculadora en Qt
  #2 (permalink)  
Antiguo 15/02/2015, 12:39
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Duda sobre promoted widgets

"Promote" no permite editar las propiedades de un widget. Únicamente te permite usar en el designer un widget propio que no esta instalado en el editor. Al usar "promote", se genera código que permite crear el widget, pero el designer únicamente conoce las propiedades de la clase que has definido como base, por lo que no podrás acceder a las características propias del widget.
  #3 (permalink)  
Antiguo 15/02/2015, 13:14
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Duda sobre promoted widgets

Gracias eferion.

Vaya, entonces creo que he entendido el tema del promote peor de lo que pensaba

Digamos que tengo este widget personalizado:
Código C++:
Ver original
  1. #ifndef MIWIDGET_H
  2. #define MIWIDGET_H
  3.  
  4. #include <QSpinBox>
  5.  
  6. class MiWidget : public QSpinBox
  7. {
  8.     Q_OBJECT
  9.  
  10. public:
  11.     explicit MiWidget(QWidget *parent = 0);
  12.  
  13.     //mis funciones necesarias para personalizar "MiWidget" como un spinbox "adhoc"
  14. };
  15.  
  16. #endif // MIWIDGET_H

(Ahora implemento las funciones necesarias para tener un flamante SpìnBox personalizado)

Ahora entro en otro proyecto, y por medio del Designer creo un formulario en el que por ejemplo quiero tener mi SpinBox personalizado y un QLabel.
Así que añado un QSpinbox y un QLabel.
Luego (creo) copio los archivos *.h y *.cpp de mi SpinBox personalizado en el mismo sitio donde están el resto de archivos de mi nuevo proyecto.
Finalmente hago promote to... en el SpìnBox y le señalo mi clase personalizada.

Y me da error.....me estoy desviando de la duda original (es que creo que no tenía claras las ideas al hacerla), pero entonces, ¿cómo hago uso de un widget personalizado?

Gracias de nuevo
__________________
Mi calculadora en Qt

Última edición por dehm; 15/02/2015 a las 13:24
  #4 (permalink)  
Antiguo 15/02/2015, 14:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Duda sobre promoted widgets

Al usar promote le estas diciendo al editor "voy a usar un widget que no conoces. El widget es de este tipo, fiate de mi".

Al hacer prommote has tenido que indicar la ruta del fichero de cabecera. Cuando compilas, se ejecuta el moc, que lee el fichero ui y genera el código C++ que representa la ventana que has compuesto. Después llega el compilador, incorpora el fichero recién creado al proyecto y trata de generar código ejecutable.

Si el compilador no encuentra el archivo de cabecera de tu widget... O el proyecto no compila el cpp del widget, se producirá un error.

Solución:

* verifica que tanto la cabecera como la implementación del widget están correctamente añadidas al proyecto

* verifica que la ruta y nombre del fichero de cabecera es correcta en la configuración del promote
  #5 (permalink)  
Antiguo 15/02/2015, 14:26
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Duda sobre promoted widgets

Gracias una vez más, eferion:
El compilador se quejaba de que no encontraba el archivo de implementación del widget personalizado.
Lo he añadido en el archivo *.pro y ya funciona correctamente

Una última pregunta. Esta historia viene porque se supone que un QMainWindow tiene un widget central.
Pero mi proyecto tiene tres widget en el mainwindows.
Entonces....¿se supone que he de crear toda la composición, guardarla como un widget, y luego hacer uso de "promote to" para definir esa composición como el widget central?

Saludos y gracias!
__________________
Mi calculadora en Qt
  #6 (permalink)  
Antiguo 16/02/2015, 00:52
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Duda sobre promoted widgets

QMainWindow no tiene un "widget central". Lo que sucede es que QMainWindow es un diálogo especial que viene preparado para soportar barras de menús y de herramientas. Si bien es cierto que este tipo de elementos también se pueden incluir en un QDialog, en QMainWindow es más sencillo integrar estos elementos.

En un QMainWindow puedes añadir en "el espacio central" tantos widgets como quieras. Eso si, si quieres que éstos widgets sean sensibles al tamaño de la ventana no te olvides de usar corretamente los layouts :)
  #7 (permalink)  
Antiguo 16/02/2015, 13:45
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Duda sobre promoted widgets

Vaya, pues tampoco tenía las ideas muy claras sobre el pretendido "widget central".

Cita:
Si bien es cierto que este tipo de elementos también se pueden incluir en un QDialog
Y también tu respuesta me ha adelantado la siguiente que tenía en mente.
Y es que iba a preguntar si era posible integrar un QMainWindow dentro de otro. El motivo es que me gustaría que uno de los widgets tuviera una barra de tareas. En concreto me gustaría que uno de los widgets fuera un editor de texto muy básico, pero que me permitiera lo típico -fuentes, alineados y poco más- pero que tuviera su botonera y su combinación de teclas que fuera específica cuando estuviera sobre ese widget.

Entonces, por lo que dices, ¿la forma de conseguir esto es mediante un QDialog?

Gracias como siempre
__________________
Mi calculadora en Qt
  #8 (permalink)  
Antiguo 17/02/2015, 01:30
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Duda sobre promoted widgets

No he entendido muy bien lo que intentas hacer.

Si tu idea es tener dos configuraciones diferentes nada te impide crear la configuracion "completa" en la ventana y, al activar la vista "básica", ocultar todos los elementos que dejan de estar disponibles.

Entonces únicamente tienes una ventana, has reducido el código necesario para ponerla en funcionamiento y has conseguido que la ventana sea más versátil.
  #9 (permalink)  
Antiguo 17/02/2015, 03:07
Avatar de jc_moj  
Fecha de Ingreso: septiembre-2009
Ubicación: Andalucía
Mensajes: 137
Antigüedad: 14 años, 7 meses
Puntos: 12
Respuesta: Qt. Duda sobre promoted widgets

Hola

Al igual que @eferion, tampoco entinedo muy bien lo que pretendes.

Cita:
Iniciado por dehm Ver Mensaje
...En concreto me gustaría que uno de los widgets fuera un editor de texto
muy básico, pero que me permitiera lo típico -fuentes, alineados y poco más- pero que tuviera su botonera y su combinación de teclas que fuera específica cuando estuviera sobre ese widget.
¿Te refieres a poder tener varios documentos abiertos a la vez?

Saludos
  #10 (permalink)  
Antiguo 17/02/2015, 07:59
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Duda sobre promoted widgets

Bueno, gracias a ambos por el interés.


La idea es (hasta ahora tampoco me he explicado muy bien porque no lo tenía claro del todo):

Tengo mi MainWindow. Dentro de él debería de haber un tabWidget. La idea es que cada documento nuevo que se abra o cree, implique la creación de una nueva pestaña. Al estilo Firefox. Siempre manteniendo una con un "+" como nueva pestaña.

Luego, lo que debe de haber dentro de cada pestaña del tabWidget, serían dos tablas y un editor de texto, uno muy basico, pero con su barra de tareas y sus combinaciones de teclas, de forma por ejemplo de que un "Ctrl+N" dentro del editor signifique Negritas, y fuera de él signifique Nuevo

Bueno, pongo un pantallazo mas o menos de lo que pretendo:

__________________
Mi calculadora en Qt
  #11 (permalink)  
Antiguo 18/02/2015, 04:56
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Qt. Duda sobre promoted widgets

Para la botonera del editor la puedes simular con varios botones puestos en fila con un QHBoxLayout y, justo debajo, el editor.

Si tu idea es ocultar la botonera a placer, puedes meter los botones dentro de un QWidget y así puedes controlar la visibilidad de todos los botones únicamente cambiando la visibilidad del QWidget.
  #12 (permalink)  
Antiguo 18/02/2015, 13:50
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Qt. Duda sobre promoted widgets

Cita:
Iniciado por eferion Ver Mensaje
Para la botonera del editor la puedes simular con varios botones puestos en fila con un QHBoxLayout y, justo debajo, el editor.

Si tu idea es ocultar la botonera a placer, puedes meter los botones dentro de un QWidget y así puedes controlar la visibilidad de todos los botones únicamente cambiando la visibilidad del QWidget.
Hola eferion:
Uno de mis planteamientos era ese e hice algo en ese sentido. Pero temas estéticos aparte, la idea era reciclar un QmainWindow y aprovechar sus acciones y barra de tareas.

Finalmente, ya he leído que le podemos cambiar el flag a un QMainWindow para que pase de Qt::Window a Qt::Widget, y poder usarlo normalmente como tal.

Ahora la duda es que no sé hacerlo de modo gráfico. Miraré a ver, porque la idea es usar en la medida de lo posible los formularios. Creo que es mejor y mas mantenible.

Por si a alguien le vale, pongo el ejemplo:

El editor, que es un QMainWindow (sacado del libro The Book of Qt 4_ The Art of Building Qt Applications):

editor.h
Código C++:
Ver original
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QFileDialog>
  5. #include <QMessageBox>
  6. #include "ui_mainwindow.h"
  7. #include <QStatusBar>
  8. #include <QLabel>
  9.  
  10. class QLabel;
  11.  
  12. class MainWindow :  public QMainWindow,
  13.             private Ui::MainWindow
  14. {
  15.     Q_OBJECT
  16.     public:
  17.     MainWindow (QWidget* parent=0);
  18.     //~MainWindow();
  19.  
  20.     protected:
  21.     void setupActions();
  22.     void mayDiscardDocument();
  23.     void saveFile(const QString&);
  24.  
  25.     protected slots:
  26.     void newFile();
  27.     void loadFile();
  28.     void saveFile();
  29.     void saveFileAs();
  30.     void undo();
  31.     void redo();
  32.     void copy();
  33.     void cut();
  34.     void paste();
  35.     void about();
  36.     void updateStats();
  37.    
  38.     private:
  39.     QString mFilePath;
  40.     QLabel *mStatLabel;
  41. };
  42.  
  43. #endif

editor.cpp
Código C++:
Ver original
  1. #include <QtGui>
  2. #include "mainwindow.h"
  3.  
  4. MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
  5. {
  6.     setupUi(this); 
  7.     setupActions();
  8.     mFilePath="";
  9.     mStatLabel = new QLabel;
  10.     estatusBar->addPermanentWidget(mStatLabel);
  11.     connect (textEdit, SIGNAL(textChanged()), this, SLOT(updateStats()));
  12.     updateStats(); 
  13. }
  14.  
  15. void MainWindow::setupActions()
  16. {
  17.     connect(action_Quit, SIGNAL(triggered(bool)),qApp, SLOT(quit()));
  18.     connect(action_Open, SIGNAL(triggered(bool)),this, SLOT(loadFile()));
  19.     connect(action_Save, SIGNAL(triggered(bool)),this, SLOT(saveFile()));
  20.     connect(action_Save_as, SIGNAL(triggered(bool)),this, SLOT(saveFileAs()));
  21.     connect(action_New, SIGNAL(triggered(bool)),this,SLOT(newFile()));
  22.  
  23.     connect(textEdit, SIGNAL(copyAvailable(bool)),action_Copiar, SLOT(setEnabled(bool)));
  24.     connect(textEdit, SIGNAL(undoAvailable(bool)),action_Undo, SLOT(setEnabled(bool)));
  25.     connect(textEdit, SIGNAL(redoAvailable(bool)),actionRedo, SLOT(setEnabled(bool)));
  26.  
  27.     connect(action_Copiar, SIGNAL(triggered(bool)),this, SLOT(copy()));
  28.     connect(actionCut, SIGNAL(triggered(bool)),this, SLOT(cut()));
  29.     connect(actionPaste, SIGNAL(triggered(bool)),this, SLOT(paste()));
  30.    
  31.     connect(action_Undo, SIGNAL(triggered(bool)),this, SLOT(undo()));
  32.     connect(actionRedo, SIGNAL(triggered(bool)),this, SLOT(redo()));
  33.     connect(actionInfo, SIGNAL(triggered(bool)),this, SLOT(about()));
  34. }
  35.  
  36. void MainWindow::loadFile()
  37. {
  38.     mayDiscardDocument();
  39.    
  40.         QString filename = QFileDialog::getOpenFileName(
  41.                             this,
  42.                             "Selecciona un fichero para abrir",
  43.                             "",
  44.                             "Texto (*.txt *.h *.cpp)");
  45.         QFile file(filename);
  46.     if (file.open(QIODevice::ReadOnly|QIODevice::Text))
  47.     {
  48.         textEdit->setPlainText(QString::fromUtf8(file.readAll()));
  49.         mFilePath = filename;
  50.         estatusBar->showMessage(tr("File successfully loaded."), 3000);
  51.     }
  52.  
  53. }
  54.  
  55. void MainWindow::saveFile()
  56. {
  57.     if (mFilePath.isEmpty())
  58.     {
  59.         saveFileAs();
  60.     }
  61.     else
  62.     {
  63.         saveFile(mFilePath);
  64.     }
  65. }
  66.  
  67. void MainWindow::saveFile(const QString& name)
  68. {
  69.     QFile file(name);
  70.     if (file.open(QIODevice::WriteOnly|QIODevice::Text))
  71.     {
  72.         file.write(textEdit->toPlainText().toUtf8());
  73.         estatusBar->showMessage(tr("File save succesfully."),3000);
  74.         textEdit->document()->setModified(false);
  75.     }
  76. }
  77.  
  78. void MainWindow::saveFileAs()
  79. {
  80.     mFilePath = QFileDialog::getSaveFileName(this);
  81.     if(mFilePath.isEmpty())
  82.     {
  83.         return;
  84.     }
  85.     saveFile(mFilePath);
  86. }
  87.  
  88. void MainWindow::mayDiscardDocument()
  89. {
  90.     if (textEdit->document()->isModified())
  91.     {
  92.         QString filename = mFilePath;
  93.         if (filename.isEmpty()) filename = tr("Unnamed");
  94.         if (QMessageBox::question(this, tr("Save Document?"),tr("You want to create a new document, but the "
  95.             "changes in the current document %1 have not "
  96.             "been saved. How do you want to proceed?").arg(filename),
  97.             tr("Discard Changes"), tr("Save Document") ))
  98.         {
  99.             saveFile();
  100.         }
  101.     }
  102. }
  103.  
  104. void MainWindow::newFile()
  105. {
  106.     mayDiscardDocument();
  107.     textEdit->setPlainText("");
  108.     mFilePath = "";
  109. }
  110.  
  111. void MainWindow::undo()
  112. {
  113.     textEdit->document()->undo();
  114. }
  115.  
  116. void MainWindow::redo()
  117. {
  118.     textEdit->document()->redo();
  119. }
  120.  
  121. void MainWindow::copy()
  122. {
  123.     textEdit->copy();
  124. }
  125.  
  126. void MainWindow::cut()
  127. {
  128.     textEdit->cut();
  129. }
  130.  
  131. void MainWindow::paste()
  132. {
  133. textEdit->paste();
  134. }
  135.  
  136.  
  137. void MainWindow::about()
  138. {
  139.     QMessageBox::about(this, tr("About CuteEdit"),
  140.         tr("CuteEdit 1.0\nA Qt application example.\n"
  141.         "(c) 2006 Daniel Molkentin, Open Source Press"));
  142. }
  143.  
  144. void MainWindow::updateStats()
  145. {
  146.     QString text = textEdit->document()->toPlainText();
  147.     int chars = text.length();
  148.     text = text.simplified();
  149.     int words = 0;
  150.     words = text.count(" ");
  151.     if (!text.isEmpty())
  152.     {
  153.         words++;
  154.     }
  155.     QString output = tr("Characters : %1, Words: %2").arg(chars).arg(words);
  156.     mStatLabel->setText(output);
  157. }

Un Widget compuesto por dos QTableView y el editor:
miwidget.h
Código C++:
Ver original
  1. #ifndef MIWIDGET_H
  2. #define MIWIDGET_H
  3.  
  4. #include <QVBoxLayout>
  5. #include <QLabel>
  6. #include <QTableView>
  7. #include "./Editor/mainwindow.h"
  8.  
  9. class MiWidget : public QWidget
  10. {
  11.     Q_OBJECT
  12. public:
  13.     explicit MiWidget(QWidget *parent = 0);
  14.  
  15. signals:
  16.  
  17. public slots:
  18.  
  19. private:
  20.     QVBoxLayout* lienzo;
  21.     MainWindow* editor;
  22.     QTableView* tabla1;
  23.     QTableView* tabla2;
  24.  
  25. };
  26.  
  27. #endif // MIWIDGET_H

miwidget.cpp
Código C++:
Ver original
  1. #include "miwidget.h"
  2.  
  3. MiWidget::MiWidget(QWidget *parent) :
  4.     QWidget(parent)
  5. {
  6.     lienzo = new QVBoxLayout;
  7.     editor= new MainWindow;
  8.     tabla1= new QTableView;
  9.     tabla2= new QTableView;
  10.     editor->setWindowFlags(editor->windowFlags() & ~Qt::Window); //opcionalmente editor->setWindowFlags(Qt::Widget) ?
  11.     lienzo->addWidget(tabla1);
  12.     lienzo->addWidget(tabla2);
  13.     lienzo->addWidget(editor);
  14.     this->setLayout(lienzo);
  15. }

El MainWindow "padre":

Código C++:
Ver original
  1. #ifndef MAINMAINWINDOW_H
  2. #define MAINMAINWINDOW_H
  3.  
  4. #include "ui_mainmainwindow.h"
  5. #include "miwidget.h"
  6.  
  7. class MainMainWindow : public QMainWindow, private Ui::MainMainWindow
  8. {
  9.     Q_OBJECT
  10.  
  11. public:
  12.     explicit MainMainWindow(QWidget *parent = 0);
  13.  
  14. private:
  15.     MiWidget* central;
  16. };
  17.  
  18. #endif // MAINMAINWINDOW_H

Código C++:
Ver original
  1. #include "mainmainwindow.h"
  2.  
  3. MainMainWindow::MainMainWindow(QWidget *parent) :
  4.     QMainWindow(parent)
  5. {
  6.     setupUi(this);
  7.     central = new MiWidget(this);
  8.  
  9.     this->setCentralWidget(central);
  10.  
  11.  
  12. }

Y el resultado:
__________________
Mi calculadora en Qt

Última edición por dehm; 18/02/2015 a las 13:56

Etiquetas: widgets
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:45.