开发者

How to write a GUI for a large cross-platform C++ project?

I have a large cross-platform (Linux and Windows) C++ project, for which I want to create a GUI.

I have few very general questions about the basic principles of GUI for such project:

  1. Should the GUI be separated from the application's lo开发者_如何学JAVAgic?
  2. If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?
  3. Is it a good idea to have the GUI in a language different than a C++? If yes - which language?
  4. Is it a good idea to have a browser-based GUI?
  5. Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?


  1. Should the GUI be separated from the application's logic?

    Yes, definitely....

  2. If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

    ...but not that much. Sockets would be overkill (exception: see question 5). Usually you split up the classes in GUI and backend parts. The GUI classes then call methods of the backend.

  3. Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

    If so, you would have to integrate the two languages, so I would recommend writing everything in the same language. But to answer your question, you could for example create Python bindings for your backend and write the GUI in Python (with PyGTK, PyQT or wxWidgets).

  4. Is it a good idea to have a browser-based GUI?

    That depends on how you want to deploy your application. If it should be installed on each client computer, a web interface doesn't make sense. If you want to host it centrally, then you might opt for a web interface.

  5. Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

    I think this makes sense only if the backend must be some kind of secure (i.e. must not be installed on users' computers) or if you have a thin client-like approach as in question 4. Writing cross-platform GUIs is much easier than writing cross-platform backends (in my opinion), so you should rather do both parts cross-platform. By the way, .NET-based GUIs are not Windows-only - Mono already supports a great subset of Windows Forms, for example (but not WPF, sadly).

EDIT:

Concerning your Mono question: Mono is mostly stable, but not everything is yet implemented. To be sure, you can run The Mono Migration Analyzer (MoMA) to find out if something will not work in Mono. But I think the fact that so many companies are successfully using Mono in production environments means that you should at least consider Mono as an option!


Should the GUI be separated from the application's logic?

It should, because the UI widgets are just types of objects and one of the rules of OO says that each object should be trusted with the responsabilities that it can fulfill. A dialog doesn't know much about serialization for example.

If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

It depends on how much separation you need. I use asynchronous messages for communication, and then I can use different transport layers without many changes. TCP/IP would allow you to use the GUI on a separate machine from the core, but it has higher overhead than passing around window messages for example.

Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

Ideally, you should use as few languages as possible unless you really need the technical capabilities of a certain language. GUIs are more of a library problem than a language problem, so if you can find a very good C++ UI library (hint: Qt), you should code all your program in C++.

Is it a good idea to have a browser-based GUI?

It could be, but you should think about requirements and not ideas. Do your customers want to interact with your program from a browser? Can they afford the extra costs and development time? Do you have the know-how?

Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

It could be a good idea, but see the answer to #3. Also consider that you're going to work on a client-server program, which is significantly more complicated than a stand-alone program. Finally, you need to examine the pros and cons of a .NET dependency over using a C++ UI library: what .NET brings you that you couldn't get with wxWdigets, Qt, gtkmm, etc.


(1) Usually yes, this makes it possible to maintain the business logic and the user interface separately. It also enables you later to have e.g. both a browser-based SaaS user interface as well as a desktop-style local networkless operation mode and still share the whole application logic code.

(2) Not using TCP/IP sockets. Typically the application and the GUI would communicate using event and/or message passing. For example, when the application wants to notify the GUI that something happens, it creates a synthetic event that is then pushed to the event queue of the GUI. If the application is event-based also, the GUI can communicate with it by posting events. For non-blocking, quick operations the GUI can call the application logic code directly, but then the call must be guaranteed to return quickly. For slower operations, you need a separate thread anyway to process them. This thread can be the one that processes the application-side events, or you can spawn it as a worker thread when needed.

Our company's product has a user interface on top of Eclipse IDE, but part of the application logic is written in C++. The two parts communicate over CORBA, i.e. basically asynchronous event mechanism. We have been happy with this solution.

On a smaller scale, GUI applications typically separate UI and application logic using abstractions such as Model-View-Controller (MVC).

(3) It's always a hassle to integrate components written in two different components. I think you should to that only if you have an obvious platform benefit. E.g. we benefit from the Eclipse IDE components, whereas the application benefits from the raw speed of C++.

(4) Browser-based GUIs are great, but the integration with the business logic suffers from latency and the stateless mode of web servers makes the architecture cumbersome if you actually have a desktop-style application. A browser-based GUI is good for software-as-a-service applications because they don't require installation by the user and can be upgraded by the product developer at will, but if you don't plan to offer your product as a software-as-a-service product (a la e.g. Salesforce).

(5) If your application logic is cross-platform, I would try to strive to make the UI cross-platform also. Otherwise for those platforms where you only support the application logic you may need to install two operating systems, one to run the UI and one to run the application logic. There are good cross-platform user interface frameworks, at least

  • AJAX / browser-based UI
  • Trolltech/Nokia Qt
  • Eclipse (SWT)
  • Java Swing (hmm...)


it is better to use python as your base gui language with QT as gui platform. if you split gui and base program in separate processes then you can use this mechanisms for communication:

  1. signals and slots from Qt
  2. subprocess module at python
  3. local sockets.
  4. use files [write configs to file and signal other process to refresh]

but it is better to create one process and call your base language directly from python and communicate with native language's data structures. you cat use swig for this purpose. but because you can't call python functions from within C++ you can use pooling at python for some changes in shared data and do something based on this changes. i experienced two way. when i used python for GUI and management, it can be very time saving.


1. Should the GUI be separated from the application's logic?

Yes. However, see answer #2

2. If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

I believe this is a best answered by choosing a GUI framework, MFC, .NET, wxWidgets, Qt, …. The framework you choose will look after both the separation and the communication for you, as painlessly as possible.

Do not try to re-invent the wheel. The framework designers have put way more thought and testing into their implementations that you could ever afford to do.

Note that question #1 suggests that you are asking about separating the logic in a single application. However, later questions suggest you may be thinking of two separate applications, perhaps even running on separate machines.

I consider that having the GUI in a completely separate application will always result in something that will be slow and inflexible. However, if you do not care about speed and flexibility, and particularly if you already have the core application running with a simple console type interface, then this might be the best way to go.

3. Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

No.

If you are a single-person programming team, then you will be spreading yourself too thin trying to master two languages. If you are a multi-person team, why compound communication problems by setting up two different cultures?

4. Is it a good idea to have a browser-based GUI?

Not if you can avoid it. If you need a browser based GUI, then you will know it. If you do not need one then keep things simple and skip it.

5. Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

Same answer as #4


Some users already gave some good answers to your questions that's why I want to give you some tips how I handle my projects.

Q: On which OS should my application run?

Windows and Linux! -> I would use C++ or Java

Q: Is runtime speed important?

Yes! (calculations, graphing, access to system resources...) -> In view of speed C++ is often faster (not always)

Q: Is a config file required?

A: Yes! I have to set some user and system specific values. -> Could save config into registry but since we also want to use our application on linux let's use xml (rapidxml would be a good solution for C++)

Q: Is a database required?

A: Yes I have some information/calculations I need to save (local/global). -> Local: I'd use sqlite -> If you just have to save comparatively few information please consider a faster way for storing these information (xml?!)

Q: How should I structure my application?

A: ALWAYS keep apart your GUI from the "logic" part -> Makes it easier to change you code later and you'll be able to use your code for other projects as well. + the already mentioned reasons.

Q: How should I structure my GUI?

A: Think about what your application should be used for and what users should be able to do. Ah, and please don't create a too deep hierarchy which means that user shouldn't have to open 10 windows in order to open the window they want to have. Same goes for your code, it's not a wise decision to have too many objects which create a new object.

object->object->object->object->object->object->object->object

Q: Does my application has to communicate with a server application?

A: Yes? You'll have to use sockets! But keep in mind that communications via sockets aren't very fast and secure so don't use them if you don't have to.

Q: I'm not sure how to start (we are a group of developer)

A: When starting a new project I'm thinking about all these points (maybe some more) + In order to see which classes and methods I need, I start by creating a UML-Diagram which will help me to understand where I should start and the diagram will also help me to keep track of my classes and methods and how they are involved with each other. The UML-Diagram will also help your mates or clients to understand how your application will be structured.

For bigger projects I'd use C++ & wxWidgits or maybe Qt. (Just my point of view)

Rgds Layne


If you want a good example of a cross-platform GUI solution that is free and well written, may I suggest you look at wxWidgets (1). I hope this helps


My answer is very generic as you didn't tell anything about your application.

Should the GUI be separated from the application's logic?

In the code, definitely. Running in a separate process, possibly on a separate machine, might also be a good idea, but this really depends on your requirements.

Reasons to fully separate it:

  • Running application as a daemon or system service (in the background) while the GUI is not running
  • Controlling the application remotely over a network
  • Possibility of multiple independent GUI implementations, using different programming languages (e.g. iPhone?)
  • Support for automated control (scripting) without GUI
  • Implementing the separation later, if not initially done, is almost impossible

Reasons why not to separate:

  • Serialization of all I/O is required, making the implementation harder
  • Slight performance degration if very large amounts of data are transferred (this really does not affect your typical GUI application in any way)

If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

HTTP is a popular choice and it avoids most problems with firewalls and such. In C/C++ you can use libcurl for http/https requests and Boost.CGI (not yet accepted to Boost) or one of the other CGI libraries for the server side.

Other options for IPC include shared memory (Boost.Interprocess), UNIX sockets and other network protocols. However, I would not recommend these unless very large amounts of data are transferred.

Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

I don't see much benefit from this. Still, separating the GUI allows writing it - possibly even multiple implementations of it - in different languages.

Is it a good idea to have a browser-based GUI?

Definitely. If what you need can be done with HTML5 and JavaScript, do not even consider a traditional GUI, just make it a webapp instead.

The benefits are:

  • Fully cross-platform
  • No installation of software on users' machines
  • All the clients always use the latest version of the GUI
  • Web GUI frameworks are actually nicer to work with than traditional GUI frameworks are
  • No need to separate the GUI into a separate process
  • Still possible to use from scripts (e.g. using the curl program from a shell script)

On the other side, you will get slight performance degradation, but once again it doesn't affect a typical GUI application enough to matter.

Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

The APIs of cross-platform GUI libraries are somewhat horrible. Qt does pretty good job at looking native nowadays and its API is rather good, even though it has a major impact on your application. Try to restrict any usage of Qt strictly to the GUI. The other option for true native cross-platform GUI is wxWidgets, which integrates better with other C++ code, but has a very nasty and error-prone API.

For web UI, you should definitely consider Wt, which is a high-level C++ AJAX framework, with an interface similar to Qt, but using modern C++ practices instead of taking over your application like Qt does.

  • http://www.wxwidgets.org/
  • http://www.webtoolkit.eu/wt


I agree with the commentators who said 'not enough information', but depending on your needs you should give a LOT of consideration to a web browser interface.

If real time streaming data and instant gratification interactivity are not important, the web interface can be fairly straightforward with no AJAX and just trivial form-based CGI and dynamically generated HTML. Keep in mind the part that exists as the browser is being updated for you with other people's money along with any change in Windows, Linux, Mac, or other systems.

Your users already find this familiar. You can find programmers to do the job. Libraries exist already in almost every major language to embed a web server natively into an app, if needed. Or you can run a centralized server of some sort.

The browser already has a good means of separating content, input (forms), style, and enhancement where it will be easy to find people into the future who can develop or change out the relevant component.

Some people may say that's not good for standalone versions of the app, but I say that's fine for standalone as long as you add some security (run an embedded webserver where requests are only answered if they come from the local computer). The user's life can be made easier by starting the browser from the app or telling the user where to go in the startup message (the URL http://localhost:7654 or whatever, not their eternal destination :-)).


  1. Should the GUI be separated from the application's logic?

Yes.

  1. If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

TCP/IP is going too far. Separate the application logic and GUI using OOP or any other structured programming approach.

  1. Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

C++ is good enough as far as cross-platform apps are concerned. Other options are Java and .NET in which case, most of the cross-platform stuff is taken care of... though not with the degree of control that C++ provides.

  1. Is it a good idea to have a browser-based GUI?

The best idea as long as your app does not need too fine a degree of control during user-interaction.

  1. Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

IMHO the added complexity of using sockets is not worth it.

SciTE is a pretty good example a simple cross-platform application. The source code should be easy to follow for a Windows programmer. I suggest you download the source and have a look at how two platforms (Windows and GTK) have been handled the same code base.


You've god a lot of good answers, but still I'll write my own

Should the GUI be separated from the application's logic?

I think it's the best. So you can handle it easier when it come to modifications. Also, use a GUI framework that is multiplatform and has bindings for other languages, such as GTK+ or Qt.

If it is separated, how should the logic and the GUI communicate? Are TCP/IP sockets a good option? What are other possibilities?

Sockets are a good choice or via threads if it's local communication.

Is it a good idea to have the GUI in a language different than a C++? If yes - which language?

I think it's not the best option. Use the same language for everything if you can.

Is it a good idea to have a browser-based GUI?

As long as it's not too complex. I think the browser based GUIs are only for collaborative tools or absolute platform-independant (every OS has a browser) as far as you hold the main program in a server. As someone said avobe, if you consider doing a web GUI, consider first to do a webapp instead.

Even though the project's core logic is cross-platform, I can decide that the GUI will be only Windows-based (.NET?) and it will communicate with the logic on the relevant Win/Linux machine through Socket or similar method. Is it a good idea to do so?

Not in my opinion, it adds complexity, usually unnecessary, but if you really have to do that, yes, sockets are the best option.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜