Add existing sources

This commit is contained in:
2023-02-26 22:06:39 +01:00
parent b28e45d102
commit 96cdc3863b
10 changed files with 282 additions and 0 deletions

43
CMakeLists.txt Normal file
View File

@ -0,0 +1,43 @@
cmake_minimum_required(VERSION 3.16)
project(comboboxtests VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)
qt_standard_project_setup()
qt_add_executable(appcomboboxtests
main.cpp
cppdefinedmodel.h cppdefinedmodel.cpp
)
qt_add_qml_module(appcomboboxtests
URI comboboxtests
VERSION 1.0
RESOURCES
icons/movinghead.png
icons/nebelmaschine.png
icons/rgbstrahler.png
QML_FILES
Main.qml
IconComboBox.qml
IconChooserDelegateLayout.qml
)
set_target_properties(appcomboboxtests PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
target_link_libraries(appcomboboxtests
PRIVATE Qt6::Quick
)
install(TARGETS appcomboboxtests
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@ -0,0 +1,29 @@
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
RowLayout {
property string text
property string iconSource
property bool isInsideMaterialComboBox: false
id: layout
Image {
Layout.topMargin: isInsideMaterialComboBox ? 15 : 9
Layout.bottomMargin: isInsideMaterialComboBox ? 15 : 9
Layout.fillHeight: true
source: layout.iconSource
fillMode: Image.PreserveAspectFit
}
Label {
Layout.preferredHeight: layout.height
text: layout.text
verticalAlignment: Label.AlignVCenter
fontSizeMode: Text.VerticalFit
font.pixelSize: 20
}
Item {
Layout.fillWidth: true
}
}

69
IconComboBox.qml Normal file
View File

@ -0,0 +1,69 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0
ComboBox {
id: comboBox
property string iconSourceRole
delegate: ItemDelegate {
height: 64
anchors.left: parent.left
anchors.right: parent.right
contentItem: IconChooserDelegateLayout {
anchors.top: parent.top
anchors.bottom: parent.bottom
text: model[comboBox.textRole]
iconSource: model[comboBox.iconSourceRole]
}
}
contentItem: IconChooserDelegateLayout {
text: comboBox.displayText
isInsideMaterialComboBox: true
iconSource: {
// console.log("QAbstractListModel", model instanceof QAbstractListModel);
// console.log("QAbstractItemModel", model instanceof QAbstractItemModel);
// console.log("FolderListModel", model instanceof FolderListModel);
// console.log("DeviceTypesModel", model instanceof CppDefinedModel);
// console.log("QtObject", model instanceof QtObject);
if (comboBox.currentIndex < 0)
return '';
if (!comboBox.model)
return '';
if (!comboBox.iconSourceRole)
return '';
// FolderListModel has a different API
if (model instanceof FolderListModel)
return model.get(comboBox.currentIndex, iconSourceRole);
// ListModel has another different API
else if ('get' in model)
{
const data = model.get(comboBox.currentIndex);
console.log(data);
return data[iconSourceRole];
}
// and I dont know how to access C++ models from QML at all
else if ('roleNames' in model || 'data' in model)
{
if (!('roleNames' in model && 'data' in model))
throw 'roleNames or data not defined!';
const roleNames = model.roleNames();
console.log('roleNames', roleNames);
const index = model.index(comboBox.currentIndex, 0);
const data = model.data(index, 99);
console.log('data', data);
throw 'getting data from model using roleNames and data is not yet implemented.';
}
else
throw 'unknown model type: ' + typeof model;
}
}
}

84
Main.qml Normal file
View File

@ -0,0 +1,84 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material
import QtQuick.Layouts
import QtQuick.Window
import Qt.labs.folderlistmodel 2.4
import comboboxtests 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
GridLayout {
anchors.fill: parent
columns: 2
// IconComboBox shall support qml ListModels
IconComboBox {
Layout.preferredHeight: 64
id: listModelComboBox
textRole: 'theText'
valueRole: 'theValue'
iconSourceRole: 'theIconUrl'
model: ListModel {
ListElement { theText: 'text0'; theValue: 'value0'; theIconUrl: 'qrc:/comboboxtests/icons/movinghead.png' }
ListElement { theText: 'text1'; theValue: 'value1'; theIconUrl: 'qrc:/comboboxtests/icons/movinghead.png' }
ListElement { theText: 'text2'; theValue: 'value2'; theIconUrl: 'qrc:/comboboxtests/icons/nebelmaschine.png' }
ListElement { theText: 'text3'; theValue: 'value3'; theIconUrl: 'qrc:/comboboxtests/icons/nebelmaschine.png' }
ListElement { theText: 'text4'; theValue: 'value4'; theIconUrl: 'qrc:/comboboxtests/icons/rgbstrahler.png' }
ListElement { theText: 'text5'; theValue: 'value5'; theIconUrl: 'qrc:/comboboxtests/icons/rgbstrahler.png' }
}
}
Label {
text: qsTr('currentValue: ') + listModelComboBox.currentValue
}
// IconComboBox shall support qml FolderListModels (to let the user select which icon to use)
IconComboBox {
Layout.preferredHeight: 64
id: folderListModelComboBox
textRole: "fileBaseName"
valueRole: "fileBaseName"
iconSourceRole: "fileUrl"
model: FolderListModel {
folder: "qrc:/comboboxtests/icons/"
showDirs: false
function getUrlForIcon(name) {
let myFolder = folder;
if (myFolder.length < 1 || myFolder.charAt(myFolder.length - 1) !== '/') {
myFolder = myFolder + '/';
}
return myFolder + name + ".png"
}
}
}
Label {
text: qsTr('currentValue: ') + folderListModelComboBox.currentValue
}
// IconComboBox shall support C++ QAbstractListModels (access to our internal database)
IconComboBox {
Layout.preferredHeight: 64
id: cppModelComboBox
textRole: 'theText'
valueRole: 'theValue'
iconSourceRole: 'theIconUrl'
model: CppDefinedModel {
}
}
Label {
text: qsTr('currentValue: ') + cppModelComboBox.currentValue
}
Item {
Layout.fillHeight: true
}
}
}

1
cppdefinedmodel.cpp Normal file
View File

@ -0,0 +1 @@
#include "cppdefinedmodel.h"

39
cppdefinedmodel.h Normal file
View File

@ -0,0 +1,39 @@
#pragma once
#include <QAbstractListModel>
#include <qqml.h>
class CppDefinedModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
enum {
TextRole = Qt::UserRole,
ValueRole,
IconUrlRole
};
public:
using QAbstractListModel::QAbstractListModel;
int rowCount(const QModelIndex &parent) const override
{
return 6;
}
QVariant data(const QModelIndex &index, int role) const override
{
switch (role)
{
case TextRole: return QString("name%0").arg(index.row());
case ValueRole: return QString("value%0").arg(index.row());
case IconUrlRole: return QString("qrc:/comboboxtests/icons/%0.png")
.arg(std::array<const char *,3>{{"movinghead", "nebelmaschine", "rgbstrahler"}}[index.row() / 2 % 3]);
}
return {};
}
QHash<int, QByteArray> roleNames() const override
{
return {{TextRole, "theText"}, {ValueRole, "theValue"}, {IconUrlRole, "theIconUrl"}};
}
};

BIN
icons/movinghead.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
icons/nebelmaschine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
icons/rgbstrahler.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

17
main.cpp Normal file
View File

@ -0,0 +1,17 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/comboboxtests/Main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed,
&app, []() { qFatal("object creation failed!"); QCoreApplication::exit(-1); },
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}