簡體   English   中英

關於分離邏輯(C ++)和GUI(Qt)的概念和基本問題

[英]Concept of and basic questions about separating logic (C++) and GUI (Qt)

我用C++完成了一個項目。 它是一個使用CodeBlocks創建的控制台應用程序。 雖然我認為在這個問題的范圍內並不是那么重要:應用程序管理有關小公司的賬單和客戶的數據。 該程序已經完成,可以通過控制台用戶界面輕松擴展(現在,我以程序員的身份運行它)。

現在我決定學習使用Qt GUI編程和QtCreator及其QtDesigner!

不僅因為在創建GUI應用程序時將邏輯與GUI分離是一種常見做法,我想將我的項目分為兩大部分,即邏輯GUI 你已經知道邏輯部分是完整的; 我所擁有的是一個名為project的項目文件夾,其中包含另一個文件夾(CodeBlocks項目) project_logic ,它再次包含幾個類,因此頭文件和實現文件(以及一個main,當然最終會過時)。 它還包含程序讀/寫的文件。 這是寫在“純” C++和使用沒有提供手段的Qt ,這是對我很重要,它保持這種方式

現在我在project夾中添加了一個Qt項目project_gui並開始創建GUI,只實現最基本的功能,比如在對話框之間切換,關閉應用程序等等。到目前為止,它對未來的后端一無所知project_logic )。

作為第三個組件,我需要某種控制 ,它將應用程序的邏輯與GUI相關聯。 這是我的概念性問題: 在一個應用程序中將它們組合在一起的最佳方法是什么?

建議

  1. 由於project_logic可以單獨作為控制台應用程序工作,因此它已經提供了最重要的控制組件和功能。 這將保持這種方式,因為我想保持其獨立功能。 更是如此,因為我對GUI編程完全不熟悉和/或在兩周內我可能碰巧為同一邏輯創建另一個GUI。 結果是邏輯部分的類像任何其他頭一樣包含在GUI源中,並用於創建具有完整功能的程序。 驗證用戶輸入將停留在GUI部分上。 在任何情況下,程序的邏輯都是可更新的。

  2. 使GUI盡可能重用; 我應該實現第三個組件project_controlling ,它提供GUI和邏輯之間的交互(通過控制完成的用戶輸入驗證),因為兩者中的每一個都盡可能獨立嗎? GUI不包括邏輯標題,可以這么說,但包括控制標題?


我承認,第二點可能聽起來有點奇怪; 簡而言之,我的目標是:

  • 保持project_logic標准C++獨立 (在修補,添加功能等方面......)和
  • 使用Qt for GUI最大限度地(同時合理地)分離GUI和邏輯。

思路

  1. 我應該通過#include "../project_logic/header1.h" project_logic #include "../project_logic/header1.h"等包含project_logic標題嗎? (使用這些類可能有問題,我將在另一個問題中發布。)

  2. 我應該將它們作為子項目包括在內嗎?

  3. 我如何“在代碼中”連接部件?

  4. 邏輯函數是否仍然找到我之前提到的文件(讀/寫)?


請記住以下幾點: 我是GUI編程的新手! 我盡我所能來解釋我的想法/問題...但是,我知道C和C ++並編寫控制台應用程序,我用它來進行大學的模擬,並且可以很好地處理標准的東西,我想。 即使潛在的回答者想要提出一種非常不同的方法,我也會感謝我提出的概念的“解決方案”。 我在引言中解釋了這個原因。 不必提及雖然我當然有興趣聽取不同的建議。

在我做了一些研究之后,我決定發布這個問題,並且之前嘗試過“試錯”時尚。 在StackOverflow和其他主板上有很多關於這個主題的信息,所以我想提出我的想法並收集批評和輸入,而不是添加另一個“如何?” 大雜燴的問題。

由於這個問題是關於一般的方法,我可能(非常肯定...... :-P)稍后會提出更多的技術問題,我想在出現這個問題時立即編輯這個問題(超鏈接)。 但是,當然,如果有的話,這個問題的基本配方是受歡迎的。


經過一些評論和回答后,我想發布一些編輯只是為了清楚地說明:

邏輯的當前狀態

  • project_logic或多或少地在CodeBlocks中完成並編碼為CodeBlocks項目。
  • 可以作為具有“控制台用戶界面”的控制台應用程序。 (它有一個main.cpp ,現在只用於調試。)
  • 它的組件盡可能地分為類(頭文件和cpp實現文件)。

GUI的當前狀態

  • project_gui正被設置為Qt-Widget-Application項目(使用QtCreator / Designer)。
  • 到目前為止,它只是 GUI而已(不以任何方式與project_logic連接)。

目的和......

... 工作流程 ,我想跟隨,因為這是我的第一個大項目:

  • project_logicproject_gui不會離開各自的目錄; 它們都位於名為project的目錄中。 (例外: 如有必要 ,邏輯將作為dll(或類似的東西)導出,然后提供給GUI。)
  • 如果在project_logic有要更改的內容我想在CodeBlocks中這樣做(並重復可能的導出,如上所述)。
  • project_logic (或任何第三層,例如project_controlling )必須以最簡單的方式為project_gui制作一次性的...(參見第1號思路):-P

歡迎來到SO。

你真的在這里捆綁了兩三個問題,但是讓我們來看看:

作為第三個組件,我需要某種控制,它將應用程序的邏輯與GUI相關聯。

由於您使用的是Qt,因此您可以對此問題進行內置解答:

Qt項目 - 模型/視圖編程 為了幫助您入門:

模型/視圖架構

模型 - 視圖 - 控制器(MVC)是源自Smalltalk的設計模式,通常在構建用戶界面時使用。 在設計模式中,Gamma等。 寫:

MVC由三種對象組成。 Model是應用程序對象,View是其屏幕顯示,Controller定義用戶界面對用戶輸入的反應方式。 在MVC之前,用戶界面設計傾向於將這些對象混為一談。 MVC將它們分離以增加靈活性和重用。

如果組合視圖和控制器對象,則結果是模型/視圖體系結構。 這仍然將數據的存儲方式與呈現給用戶的方式分開,但提供了基於相同原理的更簡單的框架。 這種分離使得可以在幾個不同的視圖中顯示相同的數據,並實現新的視圖類型,而無需更改底層數據結構。 為了靈活處理用戶輸入,我們引入了委托的概念。 在此框架中擁有委托的優勢在於它允許自定義數據項的呈現和編輯方式。

QT框架明確支持的MVC模型(並且可能與其他GUI框架一起實現,盡管工作量更大)被廣泛接受為一組健壯,靈活的設計模式,可以管理和分離各種應用程序層,以你正在考慮的方式 - 所以你走在正確的軌道上。

我承認,第二點可能聽起來有點奇怪; 簡而言之,我的目標是......

如何設置源代碼項目的問題實際上與您的應用程序架構本身無關,盡管這些區域通常相互交叉,以便良好的項目組織有助於更輕松地實現架構,反之亦然。 如何組織項目及其各種庫和類可能不僅取決於您現在正在進行的項目,還取決於未來項目的計划。 例如,正如您所提到的,您可能希望設計可用於多個不同應用程序的某些GUI組件。 如果是這樣,您可能希望將GUI模塊放入可由許多應用程序使用的單獨的可重用通用庫中。

然而,某些規則是全面適用的,大多數經驗豐富的開發人員都遵循這些規則 - 這里有一些大規模,還有更多規則:

  • 每個單元一個主要類及其朋友類(hpp / cpp文件)。

  • 要非常小心頭文件中包含的內容以及您留給CPP文件的內容。 你可以在這里找到關於這個主題的指南和關於這個主題的任何好的C ++書籍,這非常重要,特別是在復雜的項目中。 (從它的聲音 - 例如你關於如何在代碼中使用#include和“連接部分”的問題 - 你需要更好地掌握C ++編程的一些基礎知識。一些優秀的書籍在那里 - 你可以在這里找到列表.C ++ Primer(第5版)是最好的起點之一。)

  • 根據功能細分您的類和庫。 大多數IDES支持項目中的虛擬子文件夾(不確定Code :: Blocks),以幫助以這種方式保持組織。 這實際上涉及到基本的設計問題,而不僅僅是如何在項目中布置代碼。

  • 避免 緊耦合!

    在軟件工程中,耦合或依賴是每個程序模塊依賴於其他每個模塊的程度。

    耦合通常與凝聚力形成對比。 低耦合通常與高內聚相關,反之亦然。 低耦合通常是結構良好的計算機系統和良好設計的標志,並且當與高內聚相結合時,支持高可讀性和可維護性的一般目標。

  • 充分利用命名空間 ,這是另一個很棒的語言功能,可以幫助保持模塊化和組織化。

在您的情況下,您可能想要做的是將您的“應用程序邏輯”打包到一個庫中,將您的通用GUI模塊打包成第二個,然后打包第三個瘦的可執行文件 - 可能只包含main()和幾行到完成任務后關閉它們 - 啟動Qt應用程序並初始化庫中的類,這些類使用MVC模型進行交互並完成應用程序的實際工作。 不需要三個單獨的模塊,盡管它將更“通用”並且可重復使用“並且更容易以這種方式保持組織。

您真的已經通過這個問題觸及了各種各樣的主題,並且其中一些主題與C ++編程基礎相關,而不僅僅是“將應用程序邏輯與GUI分離”。 希望這個答案有助於您朝着正確的方向前進。

一個重要的注意事項: GUI編程是一個完整且不是特別容易編程的分支。 有GUI專家,並且只有最低限度地使用GUI的程序員。 (我是后一組之一)。 有一個名為User Experience的SE站點,雖然它本身不涉及GUI 編程 ,但它處理用戶與系統交互的方式,這與GUI編程技術直接相關。 所以,當你說“現在我決定學習GUI編程”時,要知道你正在做大工作。 如果您真的不想將GUI編程作為您的專業,那么您可能需要考慮使用向導和預制的GUI解決方案,而不是手動完成。 QtCreator確實提供了一些這樣的支持,Code :: Blocks也是如此。 如果您打算開展這項重要業務,也可以使用商業框架。 除非你只是為了學習而這樣做,否則不建議重新發明輪子用於嚴肅的商業編程工作。

  • 如果您有單獨的項目

當您在不同項目中開發應用程序的不同部分時,最簡單的方法是將主項目與庫鏈接並使用它們。 因此,在您的情況下,您應該為CodeBlocks中開發和編譯的項目邏輯提供dll到您的Qt項目,鏈接到它並使用類。

例如,您可以將庫的頭文件放在名為Logic的文件夾中,並將.lib文件的調試版和發行版放在相關文件夾中,並鏈接您的應用程序:

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/Logic/release/ -lLogic
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/Logic/debug/ -lLogic

INCLUDEPATH += $$PWD/Logic
DEPENDPATH += $$PWD/Logic
  • 如果您在一個Qt項目中擁有所有內容

在這種情況下,使用Subdirs將代碼模塊彼此分開是一個好主意。 這樣,您就可以擁有可重復使用且可以輕松更改的獨立軟件模塊。 它還使項目更清晰,更易於閱讀。

在這種方法中,模塊可以通過信號和槽相互作用,這使得不同的部件完全獨立,並且改變一個模塊不需要改變其他部件。

Qt Creator提供良好的自動化,使部件彼此喜歡。 您可以創建Subdirs項目並將子項目添加到其.pro文件中:

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \
    Component1 \
    Component2 \
    Component3 \
    MainApp \

您應該首先在列表中引入其他人所依賴的子項目。 另請注意,子項目的.pro文件的名稱應與其文件夾名稱相同。 這樣可以檢測子項目並在“項目”窗格中列出。

子項目Component1Component2Component3可以是庫。 Component1的.pro文件的一部分:

TARGET = Component1
TEMPLATE = lib

DEFINES += COMPONENT1_LIBRARY

SOURCES += ...
HEADERS += ...

子項目MainApp可以是應用程序。 MainApp的.pro文件的MainApp

TARGET = MainApp
TEMPLATE = app

您可以通過將每個子項目鏈接到子項目來使用它們。 這可以通過右鍵單擊子項目並選擇“添加庫”然后選擇“內部庫”來完成。 從子項目列表中選擇一個庫時,鏈接配置會自動添加到.pro中。 它會像:

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../Component1/release/ -lComponent1
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../Component1/debug/ -lComponent1
else:unix: LIBS += -L$$OUT_PWD/../Component1/ -lComponent1

INCLUDEPATH += $$PWD/../Component1
DEPENDPATH += $$PWD/../Component1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM