Juce實現Table自定義

Juce實現Table自定義

一.總體展示概及概述

在項目中Juce中TableList往往無法滿足用戶需求,頭部和背景及背景顏色設置以及在Cell中添加自定義按鈕,所以需要自己實現自定義TabelList,該示例是展示實現自定義TableList,實現自定義標題頭及Item,程序員在使用過程中可以自己修改顏色皮膚,按需求實現相關功能。總體展示示例如下:

請添加圖片描述

二.實現步驟

1.實現自定義TableListModel

實現TableListModel的背景繪制,繪制單元格,及重新實現單元格生成的控件函數,繪制單元格邊線。

#pragma once#include <JuceHeader.h>
#include "TabelLookAndFeel.h"
#include "TableLabel.h"
#include "TabelOperCell.h"
#include <vector>
using namespace juce;class CustomTableModel :public juce::TableListBoxModel,public Label::Listener,public TabelOperComponent::Listener
{
public:struct TableItemInfo{std::string str_time_;std::string str_name_;bool b_checked = false;TableItemInfo(const std::string& str_time, const std::string& str_name,bool bChecked=false):str_time_(str_time), str_name_(str_name),b_checked(bChecked){}};public:CustomTableModel(std::vector<TableItemInfo>& items):vec_table_item_(items){}~CustomTableModel(){}int getNumRows() override{return vec_table_item_.size();}void paintRowBackground(juce::Graphics& g, int rowNumber, int width, int height, bool rowIsSelected) override{// 繪制行背景顏色juce::Colour bgColour(2,75,96);// = juce::Colour(8, 82.120);/* rowNumber % 2 ? juce::Colours::white//: juce::Colour(0xfff8f8f8);*/if (rowIsSelected)bgColour = Colour(127,191,127);g.fillAll(bgColour);// 繪制行底部分隔線//g.setColour(Colour(52,110,127));//g.drawLine(0, height - 1, width, height - 1);}void paintCell(juce::Graphics& g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) override{//if (columnId != 1) // 非復選框列{// 設置文本樣式g.setFont(juce::Font(14.0f));//g.setColour(rowIsSelected ? juce::Colours::black : juce::Colours::darkgrey);g.setColour(Colours::white);if (vec_table_item_.size() > rowNumber){if (columnId == 1){g.drawText(std::to_string(rowNumber+1), juce::Rectangle<int>(0, 0, width, height),juce::Justification::centred, true);}//else if (columnId == 2)//    g.drawText(vec_table_item_[rowNumber].str_name_.c_str(), juce::Rectangle<int>(0, 0, width, height),//        juce::Justification::centred, true);else if (columnId == 3)g.drawText(vec_table_item_[rowNumber].str_time_.c_str(), juce::Rectangle<int>(0, 0, width, height),juce::Justification::centred, true);}}// 繪制方格線g.setColour(Colour(52, 110, 127));//g.drawRect(0, 0, width, height);//g.drawLine(0, 0, width, 0, 2); // 繪制上邊線g.drawLine(0, 0, 0, height, 2); // 繪制左邊線g.drawLine(0, height, width, height, 2);// 繪制下邊線if (columnId == 4)g.drawLine(width, 0, width, height, 2); // 繪制右邊線}juce::Component* refreshComponentForCell(int rowNumber, int columnId, bool isRowSelected,juce::Component* existingComponentToUpdate) override{if (columnId == 2) // 復選框列{TabelLabel* label = static_cast<TabelLabel*>(existingComponentToUpdate);if (label == nullptr){label = new TabelLabel();label->setRow(rowNumber);label->setText(vec_table_item_[rowNumber].str_name_.c_str(),dontSendNotification);label->setEditable(true, true, false);label->addListener(this);}if (rowNumber < data.size()){label->setText(data[rowNumber][columnId - 1], juce::dontSendNotification);}return label;}else if (columnId == 4){TabelOperComponent* oper = static_cast<TabelOperComponent*>(existingComponentToUpdate);if (oper == nullptr){oper = new TabelOperComponent();oper->setRow(rowNumber);}return oper;}return nullptr;}// 設置 TableListBox 指針void setTable(juce::TableListBox* tableListBox){table = tableListBox;}// 處理標簽文本更改事件void labelTextChanged(juce::Label* label) override{TabelLabel* label_new = static_cast<TabelLabel*>(label);int row = label_new->getRow();}void itemClicked(TabelOperComponent* oper, int type) override{int row = oper->getRow();}
private:juce::Array<juce::StringArray> data;juce::TableListBox* table = nullptr;std::vector<TableItemInfo>& vec_table_item_;juce::Array<bool> toggleStates;//CustomToggleLookAndFeel customToggleLookAndFeel;JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CustomTableModel)
};
2.實現TableList的標題頭

繼承自LookAndFeel_V4 繪制Border,繪制列及繪制背景色

#pragma once
#include <JuceHeader.h>
using namespace juce;class CustomTableHeaderLookAndFeel : public juce::LookAndFeel_V4
{
public:void drawTableHeaderBackground(juce::Graphics& g, juce::TableHeaderComponent& header) override{// 繪制表頭背景//auto color = ;auto color = Colours::black.fromFloatRGBA(0, 0, 0, 0.25);g.fillAll(color);}// 新增繪制表格邊框的方法void drawTableBorder(juce::Graphics& g, juce::TableListBox& table){g.setColour(juce::Colour(52, 110, 127)); // 設置邊框顏色juce::Rectangle<int> bounds = table.getLocalBounds();// 繪制上邊框g.drawLine(bounds.getX(), bounds.getY(), bounds.getRight(), bounds.getY(), 1);// 繪制下邊框//g.drawLine(bounds.getX(), bounds.getBottom(), bounds.getRight(), bounds.getBottom(), 1);// 繪制左邊框//g.drawLine(bounds.getX(), bounds.getY(), bounds.getX(), bounds.getBottom(), 1);// 繪制右邊框//g.drawLine(bounds.getRight(), bounds.getY(), bounds.getRight(), bounds.getBottom(), 1);}void drawTableHeaderColumn(juce::Graphics& g, juce::TableHeaderComponent& header,const juce::String& columnName, int columnId,int width, int height, bool isMouseOver,bool isMouseDown, int columnFlags) override{{// 其他列的文本繪制(與item文本樣式一致)g.setFont(juce::Font(14.0f)); // 設置與item相同的字體大小g.setColour(juce::Colours::white);g.drawText(columnName, juce::Rectangle<int>(0, 0, width, height),juce::Justification::centred, true);}// 繪制列的邊框線g.setColour(Colour(52, 110, 127)); // 設置邊框線顏色//g.drawRect(0, 0, width, height, 1); // 繪制1px寬的邊框線g.drawLine(0, 0, width, 0, 2); // 繪制上邊線g.drawLine(0, 0, 0, height, 2); // 繪制左邊線g.drawLine(0, height, width, height,2);if(columnId == 4)g.drawLine(width, 0, width, height, 2); // 繪制右邊線}
};
3.在列中實現自定義button

在對應列中實現自定義component創建,如下所示:
請添加圖片描述

對應自定義component的代碼示例:簡單實現了三個按鈕,同學可以根據自己情況修改按鈕,可以增加圖標增加美觀

class TabelOperComponent : public juce::Component,public juce::ToggleButton::Listener
{
public:static const int BTN_NUM = 3;class JUCE_API  Listener{public:/** Destructor. */virtual ~Listener() = default;virtual void itemClicked(TabelOperComponent* oper,int type) = 0;};void addListener(Listener* newListener) {const ScopedLock sl(listenerLock);listeners.addIfNotAlreadyThere(newListener);}void removeListener(Listener* listenerToRemove) {const ScopedLock sl(listenerLock);listeners.removeFirstMatchingValue(listenerToRemove);}TabelOperComponent();~TabelOperComponent() override {}void setRow(int row) { row_ = row; }int  getRow() { return row_; }void paint(juce::Graphics& g) override;void resized() override;virtual void buttonClicked(Button*) override;
private:int row_ = 0;CriticalSection listenerLock;Array<Listener*> listeners;juce::ToggleButton toggleButtons[BTN_NUM];JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TabelOperComponent)
};
#include "TabelOperCell.h"
TabelOperComponent::TabelOperComponent()
{for (int i = 0; i < 3; ++i){addAndMakeVisible(toggleButtons[i]);}
}
void TabelOperComponent::paint(juce::Graphics& g)
{//g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));auto area = getLocalBounds().toFloat();g.setColour(Colour(52, 110, 127));int width = area.getWidth();int height = area.getHeight();g.drawLine(0, 0, 0, height, 2); g.drawLine(width, 0, width, height, 2); g.drawLine(0, height, width, height, 2);
}void TabelOperComponent::resized()
{auto area = getLocalBounds();int width = (area.getWidth()-6)/3;for (auto& button : toggleButtons){button.setBounds(area.removeFromLeft(width).withSizeKeepingCentre(16,16));area.removeFromLeft(2);}
}void TabelOperComponent::buttonClicked(Button* ptr_btn)
{for (int i = 0; i < BTN_NUM; i++){if (ptr_btn == &toggleButtons[i]){ScopedLock lock(listenerLock);for (int j = listeners.size(); --j >= 0;)if (auto* l = listeners[j])l->itemClicked(this,i);}}
}
4.在MainCompoent中使用自定義TableList

使用Table和LookAndFeel并自定義了Item參數結構體,設置TableList的屬性,并自定義添加Item條數。

請添加圖片描述
請添加圖片描述

請添加圖片描述

示例代碼如下:

#pragma once#include <JuceHeader.h>
#include "PresetTableComponent.h"
#include "TabelLookAndFeel.h"//==============================================================================
/*This component lives inside our window, and this is where you should put allyour controls and content.
*/
class MainComponent  : public juce::Component
{
public://==============================================================================MainComponent();~MainComponent() override;//==============================================================================void paint (juce::Graphics&) override;void resized() override;private://==============================================================================// Your private member variables go here...juce::TableListBox table_;CustomTableModel* table_model_ = nullptr;CustomTableHeaderLookAndFeel customLookAndFeel;std::vector<CustomTableModel::TableItemInfo> vec_table_item_;//TableDemoComponent table;JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
#include "MainComponent.h"//==============================================================================
MainComponent::MainComponent()
{//addAndMakeVisible(&table);table_.setLookAndFeel(&customLookAndFeel);table_.getHeader().addColumn("ID", 1, 10);table_.getHeader().addColumn("Name", 2, 10);table_.getHeader().addColumn("Time", 3, 10 * 4);table_.getHeader().addColumn("Operation", 4, 60);table_.getHeader().setSize(getWidth(), 32);table_.setColour(juce::TableListBox::backgroundColourId, Colour(2, 75, 96));table_.getViewport()->setScrollBarsShown(false, false);table_.getHeader().setPopupMenuActive(false);table_.getHeader().addMouseListener(this, false);table_.getHeader().setColumnVisible(7, false); // hide the "length" column until the user shows ittable_.setMultipleSelectionEnabled(true);addAndMakeVisible(&table_);setSize(500, 500);
}MainComponent::~MainComponent()
{
}//==============================================================================
void MainComponent::paint (juce::Graphics& g)
{// (Our component is opaque, so we must completely fill the background with a solid colour)g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));g.setFont (juce::Font (16.0f));g.setColour (juce::Colours::white);g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
}void MainComponent::resized()
{auto area = getLocalBounds();if (table_model_){table_.setModel(nullptr);delete table_model_;table_model_ = nullptr;}vec_table_item_.clear();for (int i = 0; i < 10; i++){vec_table_item_.emplace_back("2025-04-17 13:56:00", "Name1");}if (!table_model_){table_model_ = new CustomTableModel(vec_table_item_);table_.setModel(table_model_);table_model_->setTable(&table_);}auto tab_area = area;int colum_with = tab_area.getWidth() / 8;table_.setRowHeight(32);table_.getHeader().setColumnWidth(1, tab_area.removeFromLeft(colum_with).getWidth()); table_.getHeader().setColumnWidth(2, tab_area.removeFromLeft(colum_with).getWidth());table_.getHeader().setColumnWidth(3, tab_area.removeFromLeft(4 * colum_with).getWidth());table_.getHeader().setColumnWidth(4, tab_area.getWidth());table_.getHeader().setSize(getWidth(), 32);table_.getHeader().getProperties().set("allSelected", false);table_.setBounds(area);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82391.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82391.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82391.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ set數據插入、set數據查找、set數據刪除、set數據統計、set排序規則、代碼練習1、2

set數據插入&#xff0c;代碼見下 #include<iostream> #include<set> #include<vector>using namespace std;void printSet(const set<int>& s) {for (set<int>::const_iterator it s.begin(); it ! s.end(); it) {cout << *it <…

深度學習賦能圖像識別:技術、應用與展望

論文&#xff1a; 一、引言? 1.1 研究背景與意義? 在當今數字化時代&#xff0c;圖像作為信息的重要載體&#xff0c;廣泛存在于各個領域。圖像識別技術旨在讓計算機理解和識別圖像內容&#xff0c;將圖像中的對象、場景、行為等信息轉化為計算機能夠處理的符號或數據 &am…

深入解析C++引用:從別名機制到函數特性實踐

1.C引用 1.1引用的概念和定義 引用不是新定義?個變量&#xff0c;而是給已存在變量取了?個別名&#xff0c;編譯器不會為引用變量開辟內存空間&#xff0c;它和它引用的變量共用同?塊內存空間。比如四大名著中林沖&#xff0c;他有一個外號叫豹子頭&#xff0c;類比到C里就…

【從0-1的HTML】第1篇:HTML簡介

1 HTML簡介 HTML是用來描述網頁的一種語言,是超文本標記語言的縮寫(Hyper Text Markup Language),不屬于編程語言的范疇&#xff0c;屬于一種標記語言。 標記語言使用一套標記標簽(Markup tag)&#xff0c;又稱為標簽,HTML就是使用標記標簽來描述網頁。 1.2 HTML標簽 1、HTM…

vue+cesium示例:地形開挖(附源碼下載)

基于cesium和vue繪制多邊形實現地形開挖效果&#xff0c;適合學習Cesium與前端框架結合開發3D可視化項目。 demo源碼運行環境以及配置 運行環境&#xff1a;依賴Node安裝環境&#xff0c;demo本地Node版本:推薦v18。 運行工具&#xff1a;vscode或者其他工具。 配置方式&#x…

qwen大模型在進行詞嵌入向量時,針對的詞表中的唯一數字還是其他的?

qwen大模型在進行詞嵌入向量時,針對的詞表中的唯一數字還是其他的? Qwen大模型進行詞嵌入向量時,針對的是詞表中每個 Token 對應的唯一數字(Token ID) ,核心邏輯結合詞表構建、嵌入過程展開 一、Qwen 詞表與 Token ID Qwen 用 BPE 分詞器(基于 tiktoken,以 cl100k 為…

動態規劃-1143.最長公共子序列-力扣(LeetCode)

一、題目解析 對于給定了兩個字符串中&#xff0c;需要找到最長的公共子序列&#xff0c;也就是兩個字符串所共同擁有的子序列。 二、算法原理 1、狀態表示 dp[i][j]&#xff1a;表示s1的[0,i]和s2的[0,j]區間內所有子序列&#xff0c;最長子序列的長度 2、狀態轉移方程 根…

互聯網c++開發崗位偏少,測開怎么樣?

通過這標題&#xff0c;不難看出問這個問題的&#xff0c;就是沒工作過的。如果工作過&#xff0c;那就是不斷往深的鉆研&#xff0c;路越走越窄&#xff0c;找工作一般就是找原來方向的。沒工作過的&#xff0c;那一般就是學生。 學生找什么方向的工作比較好&#xff1f; 學生…

推薦算法八股

跑路了&#xff0c;暑期0offer&#xff0c;華為主管面掛了&#xff0c;真幽默&#xff0c;性格測評就掛了居然給我一路放到主管面&#xff0c;科大迅飛太囂張&#xff0c;直接跟人說后面要面華為&#xff0c;元戎啟行&#xff0c;學了C后python完全忘了怎么寫&#xff0c;挺尷尬…

Spring Boot微服務架構(九):設計哲學是什么?

一、Spring Boot設計哲學是什么&#xff1f; Spring Boot 的設計哲學可以概括為 ??“約定優于配置”?? 和 ??“開箱即用”??&#xff0c;其核心目標是??極大地簡化基于 Spring 框架的生產級應用的初始搭建和開發過程??&#xff0c;讓開發者能夠快速啟動并運行項目…

前端導入Excel表格

前端如何在 Vue 3 中導入 Excel 文件&#xff08;.xls 和 .xlsx&#xff09;&#xff1f; 在日常開發中&#xff0c;我們經常需要處理 Excel 文件&#xff0c;比如導入數據表格、分析數據等。文章將在 Vue 3 中實現導入 .xls 和 .xlsx 格式的文件&#xff0c;并解析其中的數據…

C++和C#界面開發方式的全面對比

文章目錄 C界面開發方式1. **MFC&#xff08;Microsoft Foundation Classes&#xff09;**2. **Qt**3. **WTL&#xff08;Windows Template Library&#xff09;**4. **wxWidgets**5. **DirectUI** C#界面開發方式1. **WPF&#xff08;Windows Presentation Foundation&#xf…

刷leetcode hot100返航必勝版--鏈表6/3

鏈表初始知識 鏈表種類&#xff1a;單鏈表&#xff0c;雙鏈表&#xff0c;循環鏈表 鏈表初始化 struct ListNode{ int val; ListNode* next; ListNode(int x): val&#xff08;x&#xff09;,next(nullptr) {} }; //初始化 ListNode* head new ListNode(5); 刪除節點、添加…

軟考 系統架構設計師系列知識點之雜項集萃(78)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;77&#xff09; 第139題 以下關于軟件測試工具的敘述&#xff0c;錯誤的是&#xff08;&#xff09;。 A. 靜態測試工具可用于對軟件需求、結構設計、詳細設計和代碼進行評審、走查和審查 B. 靜…

【Unity】云渲染

1 前言 最近在搞Unity云渲染的東西&#xff0c;所以研究了下官方提供的云渲染方案Unity Renderstreaming。注&#xff1a;本文使用的Unity渲染管線是URP。 2 文檔 本文也只是介紹基本的使用方法&#xff0c;更詳細內容參閱官方文檔。官方文檔&#xff1a;Unity Renderstreamin…

組相對策略優化(GRPO):原理及源碼解析

文章目錄 PPO vs GRPOPPO的目標函數GRPO的目標函數KL散度約束與估計ORM監督RL的結果PRM監督RL的過程迭代RL算法流程 GRPO損失的不同版本GRPO源碼解析 DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models PPO vs GRPO PPO的目標函數 J P P O…

Linux或者Windows下PHP版本查看方法總結

確定當前服務器或本地環境中 PHP 的版本,可以通過以下幾種方法進行操作: 1. 通過命令行檢查 這是最直接且常用的方法,適用于本地開發環境或有 SSH 訪問權限的服務器。 方法一:php -v 命令 php -v輸出示例:PHP 8.1.12 (cli) (built: Oct 12 2023 12:34:56) (NTS) Copyri…

[Linux] MySQL源碼編譯安裝

目錄 環境包安裝 創建程序用戶 解壓源碼包 配置cmake ?編輯編譯 安裝 配置修改屬性 屬主和屬組替換成mysql用戶管理 系統環境變量配置 初始化數據庫 服務管理 啟動 環境包安裝 yum -y install ncurses ncurses-devel bison cmake gcc gcc-c 重點強調&#xff1a;采…

【C++項目】負載均衡在線OJ系統-1

文章目錄 前言項目結果演示技術棧&#xff1a;結構與總體思路compiler編譯功能-common/util.hpp 拼接編譯臨時文件-common/log.hpp 開放式日志-common/util.hpp 獲取時間戳方法-秒級-common/util.hpp 文件是否存在-compile_server/compiler.hpp 編譯功能編寫&#xff08;重要&a…

轉戰海外 Web3 遠程工作指南

目錄 一、明確職業目標和技能 二、準備常用軟件 &#xff08;一&#xff09;通訊聊天工具 &#xff08;二&#xff09;媒體類平臺 &#xff08;三&#xff09;線上會議軟件 &#xff08;四&#xff09;辦公協作工具 &#xff08;五&#xff09;云存儲工具 &#xff08;六…