Add existing sources
This commit is contained in:
43
CMakeLists.txt
Normal file
43
CMakeLists.txt
Normal 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})
|
29
IconChooserDelegateLayout.qml
Normal file
29
IconChooserDelegateLayout.qml
Normal 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
69
IconComboBox.qml
Normal 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
84
Main.qml
Normal 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
1
cppdefinedmodel.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "cppdefinedmodel.h"
|
39
cppdefinedmodel.h
Normal file
39
cppdefinedmodel.h
Normal 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
BIN
icons/movinghead.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
BIN
icons/nebelmaschine.png
Normal file
BIN
icons/nebelmaschine.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
icons/rgbstrahler.png
Normal file
BIN
icons/rgbstrahler.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
17
main.cpp
Normal file
17
main.cpp
Normal 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();
|
||||||
|
}
|
Reference in New Issue
Block a user