2014-09-23 19 views
32

Sto cercando di creare ed eseguire un esempio molto semplice e di base di Qt attraverso Cmake, rimuovendo il file .pro. Il seguente è il codice per progetto Qt (la struttura di directory per il progetto Qt generato automaticamente èImplementazione del progetto Qt tramite CMake

Cmake (my project name) 
├── headers 
│   └── mainwindow.h 
├── sources 
│   ├── main.cpp 
│   └── mainwindow.cpp 
└── forms 
    └── mainwindow.ui 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

main.cpp

#include "mainwindow.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

Questo è il mio CMakeLists.txt

project(Cmake) 

find_package(Qt5Widgets) 

set(CMAKE_AUTOMOC ON) 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 

QT5_WRAP_CPP(Cmake_hdr_moc mainwindow.h) 
QT5_WRAP_UI(Cmake_form_hdr mainwindow.ui) 

add_library(mainwindow ${Cmake_hdr_moc} ${Cmake_form_hdr}) 
qt5_use_modules(mainwindow Widgets) 

add_executable(Cmake main.cpp mainwindow) 
qt5_use_modules(Cmake Core Gui Widgets) 

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?> 
<ui version="4.0"> 
<class>MainWindow</class> 
<widget class="QMainWindow" name="MainWindow"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>300</height> 
    </rect> 
    </property> 
    <property name="windowTitle"> 
    <string>MainWindow</string> 
    </property> 
    <widget class="QWidget" name="centralWidget"/> 
    <widget class="QMenuBar" name="menuBar"> 
    <property name="geometry"> 
    <rect> 
    <x>0</x> 
    <y>0</y> 
    <width>400</width> 
    <height>29</height> 
    </rect> 
    </property> 
    </widget> 
    <widget class="QToolBar" name="mainToolBar"> 
    <attribute name="toolBarArea"> 
    <enum>TopToolBarArea</enum> 
    </attribute> 
    <attribute name="toolBarBreak"> 
    <bool>false</bool> 
    </attribute> 
    </widget> 
    <widget class="QStatusBar" name="statusBar"/> 
</widget> 
<layoutdefault spacing="6" margin="11"/> 
<resources/> 
<connections/> 
</ui> 

Quando costruisco il progetto ed eseguire cmake, che punti a presentare mainwindow.h indicando 'ui_mainwindow.h' Nessun file o directory.

+0

Whre è il tuo file * .ui? – Gluttton

+0

Ho modificato il post con il file .ui. Finora non ho apportato alcuna modifica a quel file, è il file generato automaticamente. – user3877872

+0

Mostrate la struttura del vostro progetto in IDE o nel file system? – Gluttton

risposta

55

Lo script ha diversi errori, inoltre alcune cose possono essere migliorate. Dopo le modifiche it will be assomiglia:

cmake_minimum_required(VERSION 3.0.2) 
project(MyProject) 

find_package(Qt5Widgets) 

set(CMAKE_AUTOMOC ON) 
set(CMAKE_AUTOUIC ON) 
set(CMAKE_INCLUDE_CURRENT_DIR ON) 

add_library(mainwindow mainwindow.cpp) 
target_link_libraries (mainwindow Qt5::Widgets) 

add_executable(MyProject main.cpp) 
target_link_libraries (MyProject mainwindow) 

Errori:

  1. sbagliato direttiva add_executable. Si tenta di aggiungere una libreria, ma per questo scopo è necessario utilizzare target_link_libraries. Così, invece di:

    add_executable(Cmake main.cpp mainwindow) 
    

    È necessario:

    add_executable(Cmake main.cpp) 
    target_link_libraries (Cmake mainwindow) 
    
  2. E un altro errore manca *.cpp file nella direttiva add_library:

    add_library(mainwindow mainwindow.cpp ${Cmake_hdr_moc} ${Cmake_form_hdr})

Recomendations:

  1. anche impostando versione di CMake sarebbe opportuno. Se si utilizza CMAKE_AUTOMOC è necessaria la versione non inferiore a 2.8.6, e se si utilizza CMAKE_AUTOUIC è necessaria la versione non inferiore a quella 3.0.2:

    cmake_minimum_required(VERSION 3.0.2) 
    
  2. Utilizzando qt5_wrap_cpp con CMAKE_AUTOMOC non è necessario.

  3. Quando si utilizza l'utilizzo di CMAKE_AUTOMOCCMAKE_AUTOUIC anziché qt5_wrap_ui sarà più appropriato.

  4. Questo script è corretto per il progetto con la seguente struttura del file system:

    Project 
    ├── CMakeLists.txt 
    ├── main.cpp 
    ├── mainwindow.cpp 
    ├── mainwindow.h 
    └── mainwindow.ui 
    

    Se si dispone di un'altra struttura che si dovrebbe usare include_directories come è stato detto da @steveire.

  5. (UPD) Dal momento che, ho scritto questa risposta, ho suggerito più volte per i principianti che cercano incontrano con Qt attraverso CMake. Si lamentano del nome inappropriato del progetto - "Cmake". Per i principianti che si incontrano con CMake è difficile capire dove cmake - è solo una parte del nome del progetto (e non è obbligatorio) e dove cmake è parte della direttiva (ed è obbligatorio). Quindi mi piacerebbe sostituire il nome del progetto da "Cmake" a "MyProject". Questo riduce la connessione tra domanda e risposta, ma d'altra parte rende la risposta più amichevole per i principianti.

  6. (UPD) Come è stato menzionato da @Erik Sjölund qt5_use_modulesis obsolete e target_link_libraries dovrebbe essere utilizzato invece.

Nota: Personalmente ho avuto esperienza senza successo con CMAKE_AUTOMOC; è buono per un progetto semplice con struttura semplice. Ho avuto problemi con il caso in cui i miei file include è stato immagazzinato nella directory separata:

. 
├── include 
│   └── QtClass.h 
└── src 
    └── QtClass.cpp 

E quando i file con lo stesso nome sono stati in diverse sottodirectory:

. 
├── NamespaceA 
│   ├── QtClass.cpp 
│   └── QtClass.h 
└── NamespaceB 
    ├── QtClass.cpp 
    └── QtClass.h 

Infine: Questo è suggerimento basato sulla mia opinione personale, ma mi piacerebbe proporre more explicit version di script senza l'utilizzo di CMAKE_AUTOMOC e CMAKE_AUTOUIC, è più prolisso ma in altra mano si ha più controllo:

cmake_minimum_required (VERSION 2.8.12) 
project (MyProject) 

find_package (Qt5Widgets) 

set (MyProjectLib_src ${PROJECT_SOURCE_DIR}/mainwindow.cpp) 
set (MyProjectLib_hdr ${PROJECT_SOURCE_DIR}/mainwindow.h) 
set (MyProjectLib_ui ${PROJECT_SOURCE_DIR}/mainwindow.ui) 
set (MyProjectBin_src ${PROJECT_SOURCE_DIR}/main.cpp) 

qt5_wrap_cpp(MyProjectLib_hdr_moc ${MyProjectLib_hdr}) 
qt5_wrap_ui (MyProjectLib_ui_moc ${MyProjectLib_ui}) 

include_directories (${PROJECT_SOURCE_DIR}) 
include_directories (${PROJECT_BINARY_DIR}) 

add_library (MyProjectLib SHARED 
    ${MyProjectLib_src} 
    ${MyProjectLib_hdr_moc} 
    ${MyProjectLib_ui_moc} 
) 
target_link_libraries (MyProjectLib Qt5::Widgets) 

add_executable(MyProject ${MyProjectBin_src}) 
target_link_libraries (MyProject MyProjectLib) 

La versione completa del codice sorgente dei progetti è disponibile allo GitLab.

+0

Sì, ha funzionato, ho usato esattamente lo script sopra, scoprendo le differenze che vorrei chiedere cosa significano le include_directory ($ {PROJECT_BINARY_DIR})? Che cosa fa? E ho rimosso anche add_library. – user3877872

+0

'include_directories ($ {PROJECT_BINARY_DIR})' dice a 'CMake' trova i file include nella directory build. Tutti i file generati vengono inseriti nella directory di build. – Gluttton

+0

@ user3877872, ho trovato la fonte di problemi, guarda il mio post per favore. – Gluttton

0

Non ci hai mostrato dove si trova CMakeLists.txt nella struttura della directory. Se è a livello superiore, allora si avrebbe

add_executable(Cmake sources/main.cpp sources/mainwindow.cpp) 

e si avrebbe bisogno

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/headers) 

In ogni caso, scoprire dove l'interfaccia utente _ *. Viene generato il file h, e aggiungere la directory con include_directories.

+0

Quando costruisco il mio progetto usando Cmake, mostra le strutture di directory come: http: // imgur .it/nntQ7O5 – user3877872

Problemi correlati