最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++使用ImGUI框架開發(fā)一個簡單程序

 更新時間:2023年08月16日 09:44:46   作者:二次元攻城獅  
ImGui?是一個用于C++的用戶界面庫,跨平臺、無依賴,支持OpenGL、DirectX等多種渲染API,下面就跟隨小編一起學習一下如何使用ImGUI框架開發(fā)一個簡單程序吧

簡介

ImGui 是一個用于C++的用戶界面庫,跨平臺、無依賴,支持OpenGL、DirectX等多種渲染API,是一種即時UI(Immediate Mode User Interface)庫,保留模式與即時模式的區(qū)別參考保留模式與即時模式。ImGui渲染非常快,但界面上有大量的數據集需要渲染可能會有一些問題,需要使用一些緩存技巧。緩存只是避免數據的更新邏輯耗時太久影響渲染,實際渲染過程不存在瓶頸。

本文最終實現的應用效果如下:

使用示例

ImGui有master、docking兩個分支,鏈接如下:

推薦使用docking分支(支持窗口停靠),本文也是使用的docking分支,先把項目下載下來。

下載示例

從github下載示例,打開examples文件夾下的項目,有很多示例可以選:

我的電腦只有example_glfw_opengl和example_win32_directx兩個系列的示例能直接運行起來,example_win32_directx的界面不知道為什么看起來很糊,所以只能選擇example_glfw_opengl3的示例來開始后續(xù)的內容。

main文件

example_glfw_opengl3項目的源文件如下:

其中,main文件有很多有用的注釋和代碼片段,下面主要介紹主題、字體部分內容。

設置ImGui風格

ImGui提供Dark、Light、Classic三種風格,示例中默認使用Dark:

// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();
// Classic在示例注釋里面沒有提及,但源碼里面有對應的函數
//ImGui::StyleColorsClassic();

Dark風格:

Light風格:

Classic 風格:

自定義配色方案可參考上面設置風格的函數實現,里面的顏色種類太多,后面會單獨寫一篇界面美化的文章。

設置字體

ImGui默認字體說實話比較難看,我還是比較喜歡微軟雅黑:

//設置微軟雅黑字體,并指定字體大小
ImFont* font = io.Fonts->AddFontFromFileTTF
(
    "C:/Windows/Fonts/msyh.ttc",
    30,
    nullptr,
    //設置加載中文
    io.Fonts->GetGlyphRangesChineseFull()
);
//必須判斷一下字體有沒有加載成功
IM_ASSERT(font != nullptr);

注意一下,一定要使用GetGlyphRangesChineseFull(),使用GetGlyphRangesChineseSimplifiedCommon()的話會有部分中文加載不出來。上面加載字體有兩個問題:固定文件路徑、內存占用過高,后面會單獨寫一篇關于字體的文章。

主循環(huán)

main函數的主循環(huán)類似其它界面框架的消息循環(huán),里面有一些示例代碼需要刪除,簡化后的代碼大致如下:

while (!glfwWindowShouldClose(window))
{
    //一些注釋...
    glfwPollEvents();
    // Start the Dear ImGui frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
    /*
    * 添加自己的代碼,App的實現見下面的代碼
    */
    App::RenderUI();
    // Rendering
    ImGui::Render();
    //一些代碼和注釋
    glfwSwapBuffers(window);
}

每幀的UI渲染都在App::RenderUI()函數里面執(zhí)行,具體實現參考下面的內容。

添加Application類

實際項目中不可能把所有UI代碼放到Main函數里面,所以添加命名為Application的頭文件和源文件用來存放UI代碼。同時,創(chuàng)建一個App的命名空間并在Application.h中引入imgui.h頭文件,在源碼中添加一些示例。

頭文件內容如下:

#pragma once
#include "imgui.h"
namespace App
{
    void RenderUI();
}

源碼文件如下:

#include "Application.h"
#include <iostream>
#include <string>
namespace App
{
    //選中結果
    bool isShowDrag=false;
    //字符串結果
    std::string text="";
    //拖拽值
    float fValue = 0.5f;
    void RenderUI()
    {
        //創(chuàng)建一個設置窗口
        ImGui::Begin("設置拖拽按鈕");
        //按鈕在單擊時返回true(大多數小部件在編輯/激活時返回true)
        if (ImGui::Button("按鈕"))
        {
            //單擊事件處理程序
        }
        //顯示一些文本(也可以使用字符串格式)
        ImGui::Text("這是一個中文字符串");
        // 緩沖區(qū)用于存儲文本輸入值
        char buffer[256] = ""; 
        ImGui::InputText("輸入框", buffer, sizeof(buffer));
        //編碼轉換
        std::string textU8 = buffer;
        ImGui::Checkbox("顯示拖拽", &isShowDrag);
        if (isShowDrag)
        {
            float value = 10.0f;
            ImGui::DragFloat(u8"值",&value);
        }
        //使用從0.0f到1.0f的滑塊編輯1個浮動
        ImGui::SliderFloat("float", &fValue, 0.0f, 1.0f);
        ImGui::SameLine();
        ImGui::Text("Value %f", fValue);
        ImGui::End();
    }
}

運行結果如下:

中文編碼問題

在上述例子中,有一個關于中文字符串的問題需要注意。默認情況下,VS使用ANSI編碼格式的字符串,因此ImGui會顯示為????。

關于這個問題,網上提供了幾種解決方案:

  • 在字符串前面添加u8前綴,例如:ImGui::Begin(u8"顯示中文");
  • 將字符串轉換為UTF-8編碼格式后再傳入,例如:ImGui::Begin(string_to_utf8("顯示中文").c_str());
  • 使用記事本將源碼文件另存為UTF-8格式(推薦使用),參考B站視頻:imgui 幫助 19

推薦使用第三種方法,它簡單快速。第一種方法實際上沒有作用,依然會顯示亂碼。第二種方法可能會導致部分代碼轉換為換行符,從而導致編譯錯誤。第三種方法只需修改文件的編碼格式,之后可以直接使用中文,無需添加u8前綴。

需要注意的是,將源碼文件另存為UTF-8格式只解決了顯示問題,并沒有解決中文輸入問題。文本框控件中的中文字符串值采用的是UTF-8格式。如果需要在代碼中打印或保存文本框的輸入值,需要將其轉換為ANSI編碼??梢詤⒖糃++字符串編碼轉換進行轉換。需要注意的是,使用標準庫版本的編碼轉換可能存在多線程bug。

界面設計

界面整體使用"左導航右內容"布局,窗口標題下面最多加一個菜單欄用來設置一下業(yè)務無關的邏輯(如界面主題、??窟x項等),界面效果見文章開頭。下面會介紹怎么創(chuàng)建這樣一個界面,包括一些需要注意的問題。

關于imgui_demo.cpp

imgui_demo.cpp有8000多行代碼,里面有各種有用的示例代碼,下面需要樹控件和??靠臻g的代碼都是從這里拷貝改造的??梢韵日{用ImGui::ShowDemoWindow()查看示例顯示效果,并根據渲染的字符串到代碼里面進行搜索,如搜索Basic trees、DockSpace等。

創(chuàng)建??靠臻g

ImGui的docking分支雖然支持??浚枰褂谜咧鲃尤?chuàng)建才能使用。把ShowExampleAppDockSpace函數從imgui_demo.cpp復制到Application.cpp的RenderUI函數里面,稍微改造刪除一些代碼、注釋。代碼如下:

void RenderUI()
{
    //p_open不需要,改成nullptr
    bool* p_open = nullptr;
    static bool opt_fullscreen = true;
    static bool opt_padding = false;
    static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;    ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
    if (opt_fullscreen)
    {
        const ImGuiViewport* viewport = ImGui::GetMainViewport();
        ImGui::SetNextWindowPos(viewport->WorkPos);
        ImGui::SetNextWindowSize(viewport->WorkSize);
        ImGui::SetNextWindowViewport(viewport->ID);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
        window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
        window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
    }
    else
    {
        dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
    }    if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
        window_flags |= ImGuiWindowFlags_NoBackground;    if (!opt_padding)
        ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("DockSpace Demo", p_open, window_flags);
    if (!opt_padding)
        ImGui::PopStyleVar();    if (opt_fullscreen)
        ImGui::PopStyleVar(2);    // Submit the DockSpace
    ImGuiIO& io = ImGui::GetIO();
    if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
    {
        ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
        ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
    }
    else
    {
        //不關閉Docking
        //ShowDockingDisabledMessage();
    }    if (ImGui::BeginMenuBar())
    {
        //菜單做一些漢化
        if (ImGui::BeginMenu("選項(Options)"))
        {
            ImGui::MenuItem("全屏(Fullscreen)", NULL, &opt_fullscreen);
            ImGui::MenuItem("填充(Padding)", NULL, &opt_padding);
            ImGui::Separator();            if (ImGui::MenuItem("標志:不分割(Flag: NoSplit)", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0)) { dockspace_flags ^=mGuiDockNodeFlags_NoSplit; }
            if (ImGui::MenuItem("標志:不調整大?。‵lag: NoResize)", "", (dockspace_flags & ImGuiDockNodeFlags_NoResize) != 0)) { dockspace_flags ^=mGuiDockNodeFlags_NoResize; }
            if (ImGui::MenuItem("標志:不??吭谥行墓?jié)點(Flag: NoDockingInCentralNode)", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) != 0)) {ockspace_flags ^= ImGuiDockNodeFlags_NoDockingInCentralNode; }
            if (ImGui::MenuItem("標志:自動隱藏選項卡欄(Flag: AutoHideTabBar)", "", (dockspace_flags & ImGuiDockNodeFlags_AutoHideTabBar) != 0)) { dockspace_flags= ImGuiDockNodeFlags_AutoHideTabBar; }
            if (ImGui::MenuItem("標志:中心節(jié)點篩選器(Flag: PassthruCentralNode)", "", (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0,pt_fullscreen)) { dockspace_flags ^= ImGuiDockNodeFlags_PassthruCentralNode; }
            ImGui::Separator();
            //不關閉菜單
           /* if (ImGui::MenuItem("Close", NULL, false, p_open != NULL))
                *p_open = false;*/
            ImGui::EndMenu();
        }
        //增加主題切換
        if (ImGui::BeginMenu("主題(Other)"))
        {
            if (ImGui::MenuItem("暗黑(Dark)")) { ImGui::StyleColorsDark(); }
            if (ImGui::MenuItem("明亮(Light)")) { ImGui::StyleColorsLight(); }
            if (ImGui::MenuItem("經典(Classic)")) { ImGui::StyleColorsClassic(); }
            ImGui::EndMenu();
        }
        //HelpMarker 不需要
        ImGui::EndMenuBar();
    }
    /**添加自己的窗口**/
    ShowTreeView();
    ShowMainView();
    ImGui::End();
}

創(chuàng)建頁面

先在Application.h文件中定義需要用到的一些函數:

#pragma once
#include "imgui.h"
namespace App
{
    //主UI函數,放??靠臻g的代碼
    void RenderUI();
    //隱藏窗口的TabBar
    void HideTabBar();
    //導航頁面
    void ShowTreeView();
    //內容頁面
    void ShowMainView();
    /*
    * 內容頁面0-5
    */
    void ShowPageView0();
    void ShowPageView1();
    void ShowPageView2();
    void ShowPageView3();
    void ShowPageView4();
}

隱藏窗口標簽欄

正常情況下窗口創(chuàng)建后會有一個標簽欄,這個很影響界面外觀需要去掉,參考github上面的issues:以編程方式完成??亢碗[藏選項卡欄。沒次創(chuàng)建窗口時,需要在ImGui::Begin前面調用,代碼如下:

#include <imgui_internal.h>
void HideTabBar()
{
    ImGuiWindowClass window_class;
    window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
    ImGui::SetNextWindowClass(&window_class);
}

創(chuàng)建導航頁面

導航頁面本質上就是一個樹控件,使用ImGui自帶的控件樣式即可,代碼也是從demo里面拷貝到Application.cpp的,如下所示:

//一級索引
int FirstIdx = 0;
//二級索引
int SecondIdx = 0;
//導航頁面
void ShowTreeView()
{
    HideTabBar();
    ImGui::Begin("導航窗口");
    if (ImGui::TreeNode("功能選項"))
    {
        for (int i = 0; i < 5; i++)
        {
            if (i == 0)
                ImGui::SetNextItemOpen(true, ImGuiCond_Once);
            if (ImGui::TreeNode((void*)(intptr_t)i, "功能 %d", i))
            {
                ImGui::Text("圖標");
                ImGui::SameLine();
                if (ImGui::SmallButton("按鈕1")) { FirstIdx = i; SecondIdx = 0; }
                ImGui::Text("圖標");
                ImGui::SameLine();
                if (ImGui::SmallButton("按鈕2")) { FirstIdx = i; SecondIdx = 1; }
                ImGui::TreePop();
            }
        }
        ImGui::TreePop();
    }
    if (ImGui::TreeNode("其它選項"))
    {
        ImGui::Text("圖標");
        ImGui::SameLine();
        if (ImGui::SmallButton("按鈕")) { }
        ImGui::TreePop();
    }
    ImGui::End();
}

注:上面的“圖標”使用圖標字體就可以顯示真正的圖標,圖標字體的加載留到后續(xù)的文章再說。

創(chuàng)建內容頁面

內容頁面根據導航的索引確定需要渲染的內容,為了避免頁面關于單調,里面加了一個表格控件和選項卡控件的示例,代碼如下:

//內容頁面
void ShowMainView()
{
    HideTabBar();
    // 清除之前的內容
    ImGui::Begin("頁面窗口");
    switch (FirstIdx)
    {
    case 0:
        ShowPageView0();
        break;
    case 1:
        ShowPageView1();
        break;
    case 2:
        ShowPageView2();
        break;
    case 3:
        ShowPageView3();
        break;
    case 4:
        ShowPageView4();
        break;
    default:
        break;
    }
    ImGui::End();
}
void ShowPageView0()
{
    ImGui::Text("功能%d -> 按鈕%d -> 頁面0", FirstIdx,SecondIdx);
    //一個表格示例
    static ImGuiTableFlags flags =
        ImGuiTableFlags_SizingFixedFit |
        ImGuiTableFlags_RowBg |
        ImGuiTableFlags_Borders |
        ImGuiTableFlags_Resizable |
        ImGuiTableFlags_Reorderable |
        ImGuiTableFlags_Hideable;
    if (ImGui::BeginTable("table0", 3, flags))
    {
        ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed);
        ImGui::TableSetupColumn("CCC", ImGuiTableColumnFlags_WidthStretch);
        ImGui::TableHeadersRow();
        for (int row = 0; row < 5; row++)
        {
            ImGui::TableNextRow();
            for (int column = 0; column < 3; column++)
            {
                ImGui::TableSetColumnIndex(column);
                ImGui::Text("%s %d,%d", (column == 2) ? "Stretch" : "Fixed", column, row);
            }
        }
        ImGui::EndTable();
    }
}
void ShowPageView1()
{
    ImGui::Text("功能%d -> 按鈕%d -> 頁面1", FirstIdx, SecondIdx);
    //選項卡示例
    ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
    if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
    {
        if (ImGui::BeginTabItem("Avocado"))
        {
            ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
            ImGui::EndTabItem();
        }
        if (ImGui::BeginTabItem("Broccoli"))
        {
            ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
            ImGui::EndTabItem();
        }
        if (ImGui::BeginTabItem("Cucumber"))
        {
            ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
            ImGui::EndTabItem();
        }
        ImGui::EndTabBar();
    }
}
void ShowPageView2() { ImGui::Text("功能%d -> 按鈕%d -> 頁面2", FirstIdx, SecondIdx); }
void ShowPageView3() { ImGui::Text("功能%d -> 按鈕%d -> 頁面3", FirstIdx, SecondIdx); }
void ShowPageView4() { ImGui::Text("功能%d -> 按鈕%d -> 頁面4", FirstIdx, SecondIdx); }

隱藏控制臺窗口

隱藏控制臺窗口一般都是調用HWND hWnd = GetConsoleWindow()獲取控制臺窗口,然后使用ShowWindow(hWnd, SW_HIDE)隱藏窗口,這里使用另一種更合理的方法。

右擊項目“屬性->鏈接器->系統(tǒng)->子系統(tǒng)”,將控制臺改為窗口,如下圖所示:

然后將main函數改成WinMain函數,代碼如下:

// Main code
//int main(int, char**)
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

如果使用的不是win32,還需要引用以下頭文件:

#include <windows.h>

順便把程序標題也改一下,代碼如下:

// Create window with graphics context
GLFWwindow* window = glfwCreateWindow(1280, 720, "演示程序", nullptr, nullptr);

打包程序

將生成的exe文件重命名為App.exe單獨放到一個文件夾,初次打開需要手動調整布局,程序退出時布局自動保存在ImGui.ini文件中。最后打包的文件如下所示:

可以看到exe文件很小,只有500多KB。

總結

待解決問題

本文記錄初次使用ImGui的整個過程,解決了使用過程中的大部分問題,但還有一些細節(jié)問題需要解決:

  • 字體內存加載方式時軟件退出報錯
  • 字體文件過大時加載耗時導致白屏
  • 程序圖標自定義,默認窗體標題欄的自定義
  • 控件外觀自定義,加載圖標字體作為控件圖標

這些問題后面會每個單獨寫一篇文章處理,目前的內容已經可以開發(fā)一些簡單的應用。

開發(fā)優(yōu)勢

ImGui界面框架是我使用過開發(fā)體驗的最好的界面框架,有種在C++中使用Winform開發(fā)的感覺,甚至比Winform開發(fā)更簡單。這里要點名吐槽MFC,如果不是工作所迫我是絕對不會用它的。個人感覺ImGui良好的開發(fā)體驗主要來自兩方面:

  • 即時UI模式降低了界面和數據之間的交互難度
  • 框架默認的布局、樣式降低了開發(fā)的心智負擔

ImGui目前主要應用在游戲開發(fā)中,但我感覺在其它領域也能很好的發(fā)揮作用,在C#中也有ImGui.Net可以使用。

附件

源代碼:提取碼: xcpw

以上就是C++使用ImGUI框架開發(fā)一個簡單程序的詳細內容,更多關于C++ ImGUI的資料請關注腳本之家其它相關文章!

相關文章

  • Qt?Qml實現任意角為圓角的矩形

    Qt?Qml實現任意角為圓角的矩形

    在?Qml?中,矩形(Rectangle)是最常用的元素之一,本文將介紹如何通過自定義?Qml?元素實現一個任意角可為圓角的矩形,感興趣的可以了解下
    2025-01-01
  • C++ Qt屬性系統(tǒng)詳細介紹

    C++ Qt屬性系統(tǒng)詳細介紹

    這篇文章主要介紹了C++ Qt屬性系統(tǒng)詳細介紹的相關資料,需要的朋友可以參考下
    2016-12-12
  • C++基于Directx MMX實現的圖像灰度轉換代碼

    C++基于Directx MMX實現的圖像灰度轉換代碼

    這篇文章主要介紹了C++基于Directx MMX實現的圖像灰度轉換代碼,需要的朋友可以參考下
    2014-08-08
  • C++基于遞歸和非遞歸算法判定兩個二叉樹結構是否完全相同(結構和數據都相同)

    C++基于遞歸和非遞歸算法判定兩個二叉樹結構是否完全相同(結構和數據都相同)

    這篇文章主要介紹了C++基于遞歸和非遞歸算法判定兩個二叉樹結構是否完全相同,若判斷二叉樹的結構和數據都相同則為完全相同.涉及C++二叉樹的創(chuàng)建、遍歷、比較等相關操作技巧,需要的朋友可以參考下
    2017-05-05
  • C++位操作實戰(zhàn)掩碼、提取與組裝

    C++位操作實戰(zhàn)掩碼、提取與組裝

    在C++編程中,位操作是基礎而強大的技術,允許在二進制級別上操作數據,對性能優(yōu)化、內存節(jié)省和底層硬件控制至關重要,文章探討了掩碼操作、字節(jié)提取與組裝等技術,并介紹了bitset類模板的使用,幫助處理二進制數據,通過實例解析如何設置、清除、檢查特定位
    2024-10-10
  • C++中事件機制的簡潔實現及需要放棄的特性

    C++中事件機制的簡潔實現及需要放棄的特性

    事件模型是被廣泛使用的好東西,但是C++標準庫里沒有現成的,現在VC11可以用在XP下了,那么就痛快的拿起C++11提供的先進設施組合出一個輕便的實現吧感興趣的朋友可以了解下,或許對你有所幫助
    2013-02-02
  • 深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    本篇文章是對Java是類型安全的語言,而C++是非類型安全的語言進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • C語言實現類似wget的進度條效果

    C語言實現類似wget的進度條效果

    這篇文章主要介紹了C語言實現類似wget的進度條效果的方法,主要是讓大家可以熟練的使用轉移符\r,這里推薦給大家,需要的小伙伴參考下。
    2015-03-03
  • C++對Json數據的友好處理實現過程

    C++對Json數據的友好處理實現過程

    在Ajax的應用中,前臺基本上會用到JSON作為數據交換格式,所以下面這篇文章主要給大家介紹了關于C++對Json數據的友好處理,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • C++List容器常用函數接口刨析

    C++List容器常用函數接口刨析

    最近我學習了C++中的STL庫中的list容器,對于常用容器,我們不僅要會使用其常用的函數接口,我們還有明白這些接口在其底層是如何實現的。所以特意整理出來一篇博客供我們學習
    2022-08-08

最新評論

永登县| 陕西省| 巴彦县| 郧西县| 姜堰市| 和硕县| 太湖县| 河西区| 商南县| 绵阳市| 三原县| 贺兰县| 阿瓦提县| 彭阳县| 博白县| 陆川县| 通化县| 定边县| 白水县| 怀宁县| 尉犁县| 揭阳市| 南宁市| 宣化县| 关岭| 海原县| 新沂市| 清河县| 大关县| 东平县| 怀集县| 齐齐哈尔市| 克山县| 凤阳县| 鲁山县| 迁西县| 措美县| 沭阳县| 进贤县| 定边县| 平安县|