2010-12-11 2 views
8

Итак, мне поручено преподавать курс программирования, который включает в себя некоторые вещи о программировании GUI на C++. Мне было интересно, какова была бы лучшая установка для этого? Linux и GCC - мои инструменты выбора.C++ и GUI для обучения

Я никогда не делал такого курса, я хороший программист на C, но не программист на С ++. Мне нужен C++, потому что тот же курс должен охватывать ООП, и насколько сложно C++ быть !? :)

+11

«как трудно может C++ быть !?» +1 Формулируя меня, смеюсь. Это простая концепция C++: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – SingleNegationElimination

+1

Что такое «некоторые вещи»? –

+0

@Alf: рисование, обновление, основанное на событиях ... обычное –

ответ

3

стоны внутренне :) C++ полностью отличается от C, а не только о ООП ...

Вы можете научить их рамки GUI кроссплатформенного как WxWidgets или Qt. Но это потребует от вас всерьез узнать о них в первую очередь. Там есть хорошая книга о wxWidgets, доступная как бесплатный PDF (кросс-платформенное программирование графического интерфейса с использованием wxWidgets) - см. http://ptgmedia.pearsoncmg.com/images/0131473816/downloads/0131473816_book.pdf.

Преимущество кросс-платформенного аспекта заключается в том, что вы можете использовать Linux и GCC все, что вам нравится, и их навыки будут перенесены на другие платформы по мере необходимости.

(Кстати, вы можете научить их CMake, а также, если вы хотите идти вниз всю портативность линию в большой путь ...)

+0

:) Да, я знаю об огромном разломе, поэтому я использовал смайлик ... Я был саркастичным. Я уверен, что мне придется много учиться, прежде чем делать это. Вероятно, мой первый курс будет сосать, но я поправляюсь, мне просто нужно вводить информацию о том, что использовать в начале. –

+0

@ Dervin: Я знаю, что вы саркастичны :) Звучит как довольно сложная позиция, в которую вы попадаете ... Я просто наблюдал за очевидным. Перила в мире в целом как бы. –

+0

Понятно, что я буду советоваться с переносимостью (используя wxWidgets), может быть, лучше всего сделать. –

10

Если ОС и GUI инструментарий ваш выбор, и он должен быть C++, и вы предпочитаете Linux - тогда рассмотрите API Nokia Qt.

Это бесплатный, с открытым исходным кодом, кросс-платформенный и высококачественный.

+1

+1 - Qt также хорошо –

+0

Yup, согласился. Раньше я слышал о QT, а не о wxWidgets. Какой из них должен быть проще для педагогических целей? –

+2

Я бы выбрал Qt, способ чище, без макросов, необходимых для кода x-платформы и т. Д. Но это только мой 0.02 €;) –

1

Для «некоторых вещей» о графическом интерфейсе, который вы описываете как «Рисование, обновление, основанное на событиях ...», то есть базовые понятия, рассмотрите Windows API.

Это легко, это бетон, и это позволяет вашим ученикам прогрессировать, чтобы обернуть все это способом OO, который является очень образованным.

Пример, который делает «Drawing, освежающие, на основе события», рисуя динамический размером эллипса (вам нужно определить три заголовка, включенный в верхней части):

#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(); 
} 

EDIT: Хорошо, возможно, Мне лучше всего разместить эти три заголовка. Это не является хорошим (полным) ответом без них. Так.

[WinAPI/обертку/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

Вы можете сделать ООП и графический интерфейс в C. Посмотрите на GTK+.

+1

Зачем идти на простой продуктивный вариант, когда вы можете сделать жизнь смехотворно тяжелой для себя ?! –

+0

@ Давид, да, почему? Я не использую GTK + в C. Но Вала великолепна. –

+0

C - это просто тяжелая работа, без исключений, без строк, без объектов. Специально для программирования графического интерфейса - это очень непродуктивный язык. Существует много языков, которые позволяют сосредоточиться на работе, а не сражаться с деталями. –

1

Если вы используете C++ и Linux, рассмотрите gtkmm.Рабочая среда GNOME Desktop основана на GTK +, а gtkmm - официальная C++-оболочка для библиотеки GTK +. Он поставляется с хорошей документацией и, что может быть важно для обучения, пытается как можно больше использовать стандартную библиотеку C++.

Другой популярный выбор Qt (который также является очень хорошим инструментарием, особенно если вам нужна кросс-платформенная совместимость) перепрофилировала большую часть стандартной библиотеки, что, вероятно, делает ее не очень хорошим выбором, если вы преподаете стандартный C++.

3

Я - фанат gtkmm и glade. Графический интерфейс не особенно красив, но это лучшая библиотека GUI от перспективы программиста на C++. Это очень проста в использовании, и это имеет смысл. На самом деле, вы можете создать красивый графический интерфейс с нуля с текстовым редактором и кодировкой. С другой стороны, разработчик полов также создает графический интерфейс с графическим интерфейсом. gtkmm безупречно подключается со стандартной библиотекой C++, но также предоставляет класс ustring, совместимый с unicode строковый класс, поддерживающий std::string. Он также поставляется с libsigc++ для механизма обработки событий. libsigC++ несколько похож на Boost.Signals в дизайне. Четкое разделение проблем в библиотеке - структура, графический интерфейс и сигналы, также хорошо отражают педагогику.

0

Для linux я могу порекомендовать ultimate++ и qt. Я лично использую qt и считаю это неплохим, за исключением некоторых реальных вещей WTF.

Что касается C++, я бы так не оценил это. c и C++ совершенно разные.

0

OpenGL графика с большинством языков является отличным началом. Это бесплатно, с открытым исходным кодом, концепции легко объясняются, и API хорошо протестирован, мощен и даже доступен на мобильных платформах, таких как iPhone или Android. Настоятельно рекомендую.

Смежные вопросы