2010-12-11 9 views
8

Por lo tanto, me han encargado que imparta un curso de programación que incluye algunas cosas sobre la programación de GUI en C++. Me preguntaba, ¿cuál sería la mejor configuración para esto? Linux y GCC son mis herramientas de elección.C++ y GUIs para enseñar

Nunca he hecho un curso como este, soy un buen programador de C pero no un programador de C++. Necesito C++ porque el mismo curso debe cubrir OOP, y ¿qué tan difícil puede ser C++? :)

+11

"¡Qué difícil puede ser C++ !?" +1 me forman risa. Este es un concepto sencillo de C++: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – SingleNegationElimination

+1

¿Qué es "algunas cosas"? –

+0

@Alf: dibujo, refrescante, basado en eventos ... el habitual –

Respuesta

3

gemidos interiormente :) C++ es completamente diferente de C, y no sólo sobre programación orientada a objetos ...

Es posible que desee enseñarles un marco GUI multiplataforma como wxWidgets o Qt. Pero eso requerirá que primero aprendas sobre ellos seriamente. Hay un buen libro sobre wxWidgets disponible como PDF gratuito (Programación de GUI multiplataforma usando wxWidgets) - consulte http://ptgmedia.pearsoncmg.com/images/0131473816/downloads/0131473816_book.pdf.

La ventaja del aspecto multiplataforma es que puede usar Linux y GCC todo lo que quiera, y sus habilidades se transferirán a otras plataformas según sea necesario.

(Por cierto, es posible que desee enseñarles CMake así, si quieres ir por toda la línea de la portabilidad de una manera grande ...)

+0

:) Sí, soy consciente de la gran diferencia, es por eso que utilicé el emoticón ... Estaba siendo sarcástico. Estoy seguro de que tendré que aprender mucho antes de hacer esto. Probablemente mi primer curso apestará, pero mejoraré, solo necesito información sobre qué usar al principio. –

+0

@Dervin: Sé que estabas siendo sarcástico :) Suena como una posición bastante difícil en la que te están metiendo ... Estaba observando lo obvio. Barandilla en el mundo en general, por así decirlo. –

+0

Más al punto, creo que tomaré su consejo sobre la portabilidad (usando wxWidgets), puede ser lo mejor que se puede hacer. –

10

Si el sistema operativo y conjunto de herramientas GUI son su elección, y debe ser C++, y usted prefiere Linux, entonces considere la API Nokia Qt.

Es gratuito, de código abierto, multiplataforma y de alta calidad.

+1

+1 - Qt también es bueno –

+0

Sí, de acuerdo. Había escuchado sobre QT antes, no tanto sobre wxWidgets. ¿Cuál debería ser más fácil para propósitos pedagógicos? –

+2

Me gustaría ir por Qt, mucho más limpio, sin material macro necesario para el código x-platform etc. Pero, eso es solo mi 0.02 €;) –

1

Para "algunas cosas" sobre GUI, que describe como "Dibujo, refrescante, basado en eventos ...", es decir, conceptos básicos, considere la API de Windows.

Es fácil, es hormigón, y le permite a sus estudiantes avanzar a envolver todo de una manera OO, que es muy educativo.

Ejemplo que hace "Dibujo, refrescante, basada en evento", dibujando una elipse dinámica de tamaño (debe definir las tres cabeceras incluido en la parte superior):

#include <winapi/wrapper/windows_h.h> 
#include <cppSupport/error_handling.h> // cppSupport::throwX, cppSupport::ExitCode 
#include <cppSupport/anti_warnings.h> // cppSupport::suppressUnusedWarningFor 

#include <iostream> 
#include <string>   // std::wstring 

using cppSupport::throwX; 
using cppSupport::ExitCode; 
using cppSupport::suppressUnusedWarningFor; 

RECT clientRectOf(HWND window) 
{ 
    RECT result; 

    GetClientRect(window, &result); 
    return result; 
} 

void drawEllipse(HDC dc, RECT const& boundingRect) 
{ 
    RECT const& r = boundingRect; 
    Ellipse(dc, r.left, r.top, r.right, r.bottom); 
} 

namespace mainWindow { 

    namespace detail { 

     void paint(HWND window, HDC dc) 
     { 
      drawEllipse(dc, clientRectOf(window)); 
     } 

     void onWmDestroy(HWND window) 
     { 
      suppressUnusedWarningFor(window); 
      PostQuitMessage(ExitCode::success()); 
     } 

     void onWmPaint(HWND window) 
     { 
      PAINTSTRUCT  info; 
      HDC const deviceContext = BeginPaint(window, &info); 

      paint(window, deviceContext); 
      EndPaint(window, &info); 
     } 

     LRESULT CALLBACK messageHandler(
      HWND  window, 
      UINT  messageId, 
      WPARAM  wParam, 
      LPARAM  lParam 
      ) 
     { 
      switch(messageId) 
      { 
      case WM_DESTROY: 
       return HANDLE_WM_DESTROY(window, wParam, lParam, onWmDestroy); 
      case WM_PAINT: 
       return HANDLE_WM_PAINT(window, wParam, lParam, onWmPaint); 
      default: 
       return DefWindowProc(window, messageId, wParam, lParam); 
      } 
     } 

     ATOM registerClass() 
     { 
      WNDCLASS const info = 
      { 
       CS_HREDRAW | CS_VREDRAW, // UINT style; 
       &messageHandler,   // WNDPROC lpfnWndProc; 
       0,       // int cbClsExtra; 
       0,       // int cbWndExtra; 
       GetModuleHandle(0),  // HINSTANCE hInstance; 
       0,       // HICON hIcon; 
       LoadCursor(0, IDC_ARROW), // HCURSOR hCursor; 
       reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1), // HBRUSH hbrBackground; 
       0,       // LPCTSTR lpszMenuName; 
       L"MainWindowClass"   // LPCTSTR lpszClassName; 
      }; 

      ATOM const result = RegisterClass(&info); 
      (result != 0) 
       || throwX("registerWindowClass: RegisterClass failed"); 
      return result; 
     } 

     ATOM classAtom() 
     { 
      static ATOM const theClassAtom = registerClass(); 
      return theClassAtom; 
     } 
    } // namespace mainWindow::detail 

    HWND create(std::wstring const& title) 
    { 
     HWND const window = CreateWindow(
      MAKEINTATOM(detail::classAtom()), // LPCTSTR lpClassName, 
      title.c_str(),      // LPCTSTR lpWindowName, 
      WS_OVERLAPPEDWINDOW,    // DWORD dwStyle, 
      CW_USEDEFAULT,      // int x, 
      CW_USEDEFAULT,      // int y, 
      CW_USEDEFAULT,      // int nWidth, 
      CW_USEDEFAULT,      // int nHeight, 
      0,         // HWND hWndParent, 
      0,         // HMENU hMenu, 
      GetModuleHandle(0),    // HINSTANCE hInstance, 
      0         // LPVOID lpParam 
      ); 
     (window != 0) 
      || throwX("createMainWindow: CreateWindow failed"); 
     return window; 
    } 

} // namespace mainWindow 

bool getMessage(MSG& message, HWND window = 0) 
{ 
    int const result = GetMessage(&message, window, 0, 0); 
    (result != -1) 
     || throwX("getMessage: GetMessage failed"); 
    return (result != 0); 
} 

ExitCode dispatchWindowMessages() 
{ 
    MSG message; 

    while(getMessage(message)) 
    { 
     TranslateMessage(&message); 
     DispatchMessage(&message); 
    } 

    assert(message.message == WM_QUIT); 
    return ExitCode(message.wParam); 
} 

ExitCode cppMain() 
{ 
    HWND const window = mainWindow::create(L"My main window"); 

    ShowWindow(window, SW_SHOWDEFAULT); 
    return dispatchWindowMessages(); 
} 

int main() 
{ 
    try 
    { 
     return cppMain(); 
    } 
    catch(std::exception const& x) 
    { 
     std::cerr << "!" << x.what() << std::endl; 
    } 
    return ExitCode::failure(); 
} 

EDITAR: OK, tal vez Debería publicar esos tres encabezados. No es una buena respuesta (completa) sin ellos. Asi que.

[winapi/envoltura/windows_h.h]:

// Copyright (c) 2010 Alf P. Steinbach 
#ifndef WINAPI_WRAPPER_WINDOWSH_H 
#define WINAPI_WRAPPER_WINDOWSH_H 

//#include <progrock/cppx/devsupport/better_experience.h> 

#ifdef _MBCS 
# error _MBCS was defined, only Unicode is supported. 
#endif 

#undef UNICODE 
#undef _UNICODE 
#undef STRICT 
#undef NOMINMAX 

#define UNICODE 
#define _UNICODE 
#define STRICT 
#define NOMINMAX 

#ifdef _WIN32_WINNT 
# if _WIN32_WINNT < 0x5000 
#  error _WIN32_WINNT < 0x5000, pre-Windows 2000 is not supported. 
# endif 
#else 
# define _WIN32_WINNT 0x5000 
#endif 

#ifdef _WIN32_IE 
# if _WIN32_IE < 0x5000 
#  error _WIN32_IE < 0x5000, that old browser/Windows shell is not supported. 
# endif 
#else 
# define _WIN32_IE 0x5000 
#endif 

#include <windows.h> 
#include <windowsx.h> 


//------------------------------------------------- g++ fixups: 

#ifndef BS_TYPEMASK 
# define BS_TYPEMASK 0x0000000F 
#endif 

#ifndef BS_PUSHBOX 
# define BS_PUSHBOX   0x0000000AL 
#endif 

#ifndef EN_ALIGN_LTR_EC 
# define EN_ALIGN_LTR_EC  0x0700 
# define EN_ALIGN_RTL_EC  0x0701 
#endif 

#ifndef LBS_COMBOBOX 
# define LBS_COMBOBOX   0x8000L 
#endif 

#endif 

[cppsupport/error_handling.h]:

#ifndef CPPSUPPORT_ERROR_HANDLING_H 
#define CPPSUPPORT_ERROR_HANDLING_H 

//-------------------------------- Dependencies: 

#include <assert.h>    // assert 
#include <stdexcept>   // std::runtime_error, std::exception 
#include <stdlib.h>    // EXIT_SUCCESS, EXIT_FAILURE 
#include <string>    // std::string, std::wstring 


//-------------------------------- Interface: 

namespace cppSupport { 

    inline bool throwX(std::string const& s) 
    { 
     throw std::runtime_error(s); 
    } 

    struct ExitCode 
    { 
     int value; 
     explicit ExitCode(int v): value(v) {} 
     operator int() const { return value; } 
     static ExitCode success() { return ExitCode(EXIT_SUCCESS); } 
     static ExitCode failure() { return ExitCode(EXIT_FAILURE); } 
    }; 

} // namespace cppSupport 
#endif 

[cppsupport/anti_warnings.h]:

#ifndef CPPSUPPORT_ANTI_WARNINGS_H 
#define CPPSUPPORT_ANTI_WARNINGS_H 

//-------------------------------- Dependencies: 

// -- None. 


//-------------------------------- Interface: 

namespace cppSupport { 

    template< class Type > 
    void suppressUnusedWarningFor(Type const&) {} 

} // namespace cppSupport 

#endif 

Cheers & hth.

3

Puede hacer OOP y GUI en C. Eche un vistazo a GTK+.

+1

¿Por qué optar por la opción productiva fácil cuando puede hacer que la vida sea ridículamente difícil para usted? –

+0

@David, sí, ¿por qué? No uso GTK + en C. Pero Vala es genial. –

+0

C es simplemente un trabajo duro, sin excepciones, sin cadenas, sin objetos. Especialmente para la programación de GUI es solo un lenguaje muy improductivo. Hay muchos idiomas que le permiten concentrarse en el trabajo a mano en lugar de luchar con los detalles sangrientos. –

1

Si está utilizando C++ y Linux, considere gtkmm.El entorno de escritorio GNOME está basado en GTK + y gtkmm es el contenedor oficial de C++ para la biblioteca GTK +. Viene con buena documentación y, lo que podría ser importante para la enseñanza, trata de usar la biblioteca estándar de C++ tanto como sea posible.

La otra opción popular Qt (que también es un muy buen juego de herramientas, especialmente si necesita compatibilidad multiplataforma) ha reimplantado gran parte de la biblioteca estándar, lo que probablemente lo convierte en una opción no tan buena si está enseñando estándar C++.

3

Soy fan de gtkmm y glade. La GUI no es particularmente bonita, pero es la mejor biblioteca de GUI disponible desde la perspectiva del programador de C++. Es muy fácil de usar y simplemente tiene sentido. De hecho, puede crear una buena GUI desde cero con nada más que un editor de texto y una codificación. Por otro lado, también está el diseñador de glade para crear GUI con una aplicación GUI. gtkmm se conecta perfectamente con la biblioteca estándar de C++, pero también proporciona la clase ustring, una clase de cadena que admite Unicode compatible con std::string. También viene con libsigc++ para el mecanismo de procesamiento de eventos. libsigC++ es algo similar a Boost.Signals en diseño. La separación clara de las preocupaciones en la biblioteca, el marco, la GUI y las señales, también funcionan bien pedagógicamente.

0

Para Linux, puedo recomendar ultimate++ y qt. Yo personalmente uso qt, y lo encuentro bastante bueno, excepto por algunas cosas reales de la WTF.

En cuanto a C++, no lo juzgaría tan fácilmente. c y C++ son bastante diferentes.

0

gráficos OpenGL con la mayoría de los idiomas es un gran comienzo. Es gratis, de código abierto, los conceptos se explican fácilmente, y la API está bien probada, es poderosa e incluso utilizable en plataformas móviles como iPhone o Android. Altamente recomendado.

Cuestiones relacionadas