First part in refactoring layout

master
Jos van den Oever 2017-09-02 13:14:20 +02:00
parent f2dc67008f
commit 30c82207ce
13 changed files with 241 additions and 162 deletions

View File

@ -34,6 +34,7 @@ find_package(Qt5 ${QT_MIN_VERSION} CONFIG
find_package(Qt5QuickControls2 EXACT ${Qt5Core_VERSION}) find_package(Qt5QuickControls2 EXACT ${Qt5Core_VERSION})
find_package(Qt5Charts EXACT ${Qt5Core_VERSION}) find_package(Qt5Charts EXACT ${Qt5Core_VERSION})
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
if (ECM_FOUND) if (ECM_FOUND)
# Find KDE Modules # Find KDE Modules

View File

@ -1,6 +1,6 @@
# Rust Qt Binding Generator # Rust Qt Binding Generator
![Rust Qt Binding](logo.svg) ![Rust Qt Binding](demo/logo.svg)
This code generator gets you started quickly to use Rust code from Qt and QML. In other words, it helps to create a Qt based GUI on top of Rust code. This code generator gets you started quickly to use Rust code from Qt and QML. In other words, it helps to create a Qt based GUI on top of Rust code.

View File

@ -1,65 +0,0 @@
import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
id: application
x: windowX
y: windowY
width: windowWidth
height: windowHeight
visible: true
TabBar {
id: bar
width: parent.width
TabButton { text: "style" }
TabButton { text: "object" }
TabButton { text: "list" }
TabButton { text: "tree" }
}
StackLayout {
width: parent.width
anchors.top: bar.bottom
anchors.bottom: parent.bottom
currentIndex: bar.currentIndex
ColumnLayout {
ComboBox {
currentIndex: qtquickIndex
model: styles
textRole: "display"
onCurrentIndexChanged: {
if (currentIndex != qtquickIndex) {
widgets.currentIndex = currentIndex;
application.close();
}
}
}
Image {
source: "logo.svg"
}
}
RowLayout {
TextField {
id: fibonacciInput
placeholderText: "Your number"
validator: IntValidator {bottom: 0; top: 100;}
Component.onCompleted: { text = demo.fibonacci.input }
onTextChanged: { demo.fibonacci.input = parseInt(text, 10) }
}
Text {
text: "The Fibonacci number: " + demo.fibonacci.result
}
}
ListView {
id: listView
model: demo.fibonacciList
delegate: Row {
Text { text: result }
}
}
Text {
id: treeView
text: "No TreeView in QtQuick Controls 2"
}
}
}

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

27
demo/qml/Fibonacci.qml Normal file
View File

@ -0,0 +1,27 @@
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Layouts 1.3
Column {
Text {
text: qsTr("Calculate the <i>nth</i> Fibonacci number")
}
TextField {
id: fibonacciInput
placeholderText: qsTr("Your number")
validator: IntValidator {
bottom: 0
top: 100
}
text: demo.fibonacci.input
onTextChanged: {
var val = parseInt(text, 10)
if (val !== demo.fibonacci.input) {
demo.fibonacci.input = val
}
}
}
Text {
text: qsTr("The Fibonacci number: ") + demo.fibonacci.result
}
}

View File

@ -0,0 +1,23 @@
import QtQuick 2.6
import QtQml.Models 2.2
import QtQuick.Controls 1.5
import QtQuick.Layouts 1.3
TableView {
id: listView
model: demo.fibonacciList
TableViewColumn {
delegate: Text {
text: styleData.row + 1
}
title: "Row"
width: 100
Component.onCompleted: resizeToContents()
}
TableViewColumn {
role: "display"
title: "Fibonacci Number"
width: 100
Component.onCompleted: resizeToContents()
}
}

View File

@ -0,0 +1,25 @@
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Layouts 1.3
RowLayout {
id: content
Layout.fillWidth: true
Image {
sourceSize.height: 2* box.height
fillMode: Image.PreserveAspectFit
source: "../logo.svg"
}
ComboBox {
id: box
currentIndex: qtquickIndex
model: styles
textRole: "display"
onCurrentIndexChanged: {
if (currentIndex !== qtquickIndex) {
widgets.currentIndex = currentIndex;
application.close();
}
}
}
}

View File

@ -0,0 +1,82 @@
import QtQuick 2.6
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
id: application
property string initialTab: "style"
property int qtquickIndex: 0
visible: true
footer: StyleSwitcher {
anchors.fill: parent
}
contentItem {
TabBar {
id: bar
width: parent.width
TabButton {
text: "object"
}
TabButton {
text: "list"
}
TabButton {
text: "tree"
}
}
StackLayout {
width: parent.width
anchors.top: bar.bottom
anchors.bottom: parent.bottom
currentIndex: bar.currentIndex
ColumnLayout {
ComboBox {
currentIndex: qtquickIndex
model: styles
textRole: "display"
onCurrentIndexChanged: {
if (currentIndex != qtquickIndex) {
widgets.currentIndex = currentIndex
application.close()
}
}
}
Image {
source: "../logo.svg"
}
}
RowLayout {
TextField {
id: fibonacciInput
placeholderText: "Your number"
validator: IntValidator {
bottom: 0
top: 100
}
Component.onCompleted: {
text = demo.fibonacci.input
}
onTextChanged: {
demo.fibonacci.input = parseInt(text, 10)
}
}
Text {
text: "The Fibonacci number: " + demo.fibonacci.result
}
}
ListView {
id: listView
model: demo.fibonacciList
delegate: Row {
Text {
text: result
}
}
}
Text {
id: treeView
text: "No TreeView in QtQuick Controls 2"
}
}
}
}

View File

@ -7,11 +7,15 @@ ApplicationWindow {
id: application id: application
property string initialTab: "style" property string initialTab: "style"
property int qtquickIndex: 0 property int qtquickIndex: 0
property var processes: ListModel { ListElement{ name: "init"} } property var processes: ListModel {
ListElement {
name: "init"
}
}
onInitialTabChanged: { onInitialTabChanged: {
for (var i = 0; i < tabView.count; ++i) { for (var i = 0; i < tabView.count; ++i) {
if (tabView.getTab(i).title === initialTab) { if (tabView.getTab(i).title === initialTab) {
tabView.currentIndex = i; tabView.currentIndex = i
} }
} }
} }
@ -26,55 +30,24 @@ ApplicationWindow {
id: processSelection id: processSelection
model: processes model: processes
} }
statusBar: StatusBar {
StyleSwitcher {
anchors.right: parent.right
}
}
TabView { TabView {
id: tabView id: tabView
anchors.fill: parent anchors.fill: parent
Tab {
title: "style"
Column {
anchors.fill: parent
anchors.margins: 5
ComboBox {
currentIndex: qtquickIndex
model: styles
textRole: "display"
onCurrentIndexChanged: {
if (currentIndex !== qtquickIndex) {
widgets.currentIndex = currentIndex;
application.close();
}
}
}
Image {
source: "logo.svg"
}
}
}
Tab { Tab {
title: "object" title: "object"
RowLayout { Fibonacci {
TextField { anchors.fill: parent
id: fibonacciInput
placeholderText: "Your number"
validator: IntValidator {bottom: 0; top: 100;}
Component.onCompleted: { text = demo.fibonacci.input }
onTextChanged: { demo.fibonacci.input = parseInt(text, 10) }
}
Text {
text: "The Fibonacci number: " + demo.fibonacci.result
}
} }
} }
Tab { Tab {
title: "list" title: "list"
TableView { FibonacciList {
id: listView anchors.fill: parent
model: demo.fibonacciList
TableViewColumn {
role: "display"
title: "Row"
width: 100
}
} }
} }
Tab { Tab {
@ -94,15 +67,15 @@ ApplicationWindow {
role: "fileSize" role: "fileSize"
} }
Component.onCompleted: { Component.onCompleted: {
var root = treeView.rootIndex; var root = treeView.rootIndex
var first = sortedFileSystem.index(0, 0, root); var first = sortedFileSystem.index(0, 0, root)
treeView.expand(first); treeView.expand(first)
} }
onSortIndicatorColumnChanged: sort() onSortIndicatorColumnChanged: sort()
onSortIndicatorOrderChanged: sort() onSortIndicatorOrderChanged: sort()
function sort() { function sort() {
var role = getColumn(treeView.sortIndicatorColumn).role; var role = getColumn(treeView.sortIndicatorColumn).role
model.sortByRole(role, treeView.sortIndicatorOrder); model.sortByRole(role, treeView.sortIndicatorOrder)
} }
} }
} }
@ -116,13 +89,13 @@ ApplicationWindow {
width: parent.width width: parent.width
placeholderText: "Filter processes" placeholderText: "Filter processes"
onTextChanged: { onTextChanged: {
processes.filterRegExp processes.filterRegExp = new RegExp(processFilterInput.text)
= new RegExp(processFilterInput.text);
} }
} }
TreeView { TreeView {
onClicked: { onClicked: {
processSelection.select(index, ItemSelectionModel.ToggleCurrent); processSelection.select(
index, ItemSelectionModel.ToggleCurrent)
} }
Binding { Binding {
target: demo.processes target: demo.processes
@ -136,7 +109,7 @@ ApplicationWindow {
model: processes model: processes
selection: processSelection selection: processSelection
selectionMode: SelectionMode.ExtendedSelection selectionMode: SelectionMode.ExtendedSelection
// selectionMode: SelectionMode.SingleSelection // selectionMode: SelectionMode.SingleSelection
sortIndicatorVisible: true sortIndicatorVisible: true
alternatingRowColors: true alternatingRowColors: true
TableViewColumn { TableViewColumn {
@ -154,17 +127,20 @@ ApplicationWindow {
onSortIndicatorColumnChanged: sort() onSortIndicatorColumnChanged: sort()
onSortIndicatorOrderChanged: sort() onSortIndicatorOrderChanged: sort()
function sort() { function sort() {
var role = getColumn(processView.sortIndicatorColumn).role; var role = getColumn(
model.sortByRole(role, processView.sortIndicatorOrder); processView.sortIndicatorColumn).role
model.sortByRole(role, processView.sortIndicatorOrder)
} }
Timer { Timer {
interval: 100; running: true; repeat: true interval: 100
running: true
repeat: true
onTriggered: { onTriggered: {
var root = processView.rootIndex; var root = processView.rootIndex
var systemd = processes.index(1, 0, root); var systemd = processes.index(1, 0, root)
if (processes.data(systemd) === "systemd") { if (processes.data(systemd) === "systemd") {
processView.expand(systemd); processView.expand(systemd)
running = false; running = false
} }
} }
} }
@ -190,14 +166,14 @@ ApplicationWindow {
target: loaderEditor.item target: loaderEditor.item
onEditingFinished: { onEditingFinished: {
if (!demo) { if (!demo) {
return; return
} }
var val = loaderEditor.item.text; var val = loaderEditor.item.text
var row = styleData.row; var row = styleData.row
if (styleData.column === 0) { if (styleData.column === 0) {
demo.timeSeries.setInput(row, val); demo.timeSeries.setInput(row, val)
} else { } else {
demo.timeSeries.setResult(row, val); demo.timeSeries.setResult(row, val)
} }
} }
} }
@ -230,7 +206,7 @@ ApplicationWindow {
title: "result" title: "result"
} }
itemDelegate: { itemDelegate: {
return editableDelegate; return editableDelegate
} }
} }
Item { Item {
@ -238,7 +214,7 @@ ApplicationWindow {
Layout.fillHeight: true Layout.fillHeight: true
Text { Text {
anchors.centerIn: parent anchors.centerIn: parent
text: "QtChart is not available."; text: "QtChart is not available."
visible: chartLoader.status !== Loader.Ready visible: chartLoader.status !== Loader.Ready
} }
Loader { Loader {

View File

@ -1,8 +1,11 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>demo.qml</file> <file>qml/demo.qml</file>
<file>chart.qml</file> <file>qml/chart.qml</file>
<file>demo-qtquick2.qml</file> <file>qml/demo-qtquick2.qml</file>
<file alias="logo.svg">../logo.svg</file> <file>logo.svg</file>
<file>qml/Fibonacci.qml</file>
<file>qml/FibonacciList.qml</file>
<file>qml/StyleSwitcher.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -73,9 +73,9 @@ impl FibonacciListTrait for FibonacciList {
&self.emit &self.emit
} }
fn row_count(&self) -> usize { fn row_count(&self) -> usize {
94 93
} }
fn result(&self, row: usize) -> u64 { fn result(&self, row: usize) -> u64 {
fibonacci(row as u32) as u64 fibonacci(row as u32 + 1) as u64
} }
} }

View File

@ -117,21 +117,21 @@ QComboBox* createStyleComboBox(Model* model) {
return box; return box;
} }
QWidget* createStyleTab(Model* model, QWidget* tabs, QComboBox* box, QStatusBar* createStatusBar(Model* model, QWidget* main, QComboBox* box,
const QString& initialTab) { const QString& initialTab) {
QRect windowRect; QRect windowRect;
auto f = [windowRect, box, tabs, model, initialTab](const QString &text) mutable { auto f = [windowRect, box, main, model, initialTab](const QString &text) mutable {
QWindow* window = getWindow(tabs); QWindow* window = getWindow(main);
bool visible = tabs->isVisible(); bool visible = main->isVisible();
if (text.startsWith("QWidgets ")) { if (text.startsWith("QWidgets ")) {
tabs->setVisible(true); main->setVisible(true);
if (window && !visible) { if (window && !visible) {
window->setX(windowRect.x()); window->setX(windowRect.x());
window->setY(windowRect.y()); window->setY(windowRect.y());
window->setWidth(windowRect.width()); window->setWidth(windowRect.width());
window->setHeight(windowRect.height()); window->setHeight(windowRect.height());
} }
setStyle(tabs, QStyleFactory::create(text.mid(9))); setStyle(main, QStyleFactory::create(text.mid(9)));
#ifdef QT_QUICK_LIB #ifdef QT_QUICK_LIB
} else { } else {
if (window) { if (window) {
@ -140,28 +140,26 @@ QWidget* createStyleTab(Model* model, QWidget* tabs, QComboBox* box,
windowRect.setWidth(window->width()); windowRect.setWidth(window->width());
windowRect.setHeight(window->height()); windowRect.setHeight(window->height());
} }
tabs->setVisible(false); main->setVisible(false);
#ifdef QTQUICKCONTROLS2 #ifdef QTQUICKCONTROLS2
if (text == "QtQuick Controls 2") { if (text == "QtQuick Controls 2") {
createQtQuick("QtQuick Controls 2", "qrc:///demo-qtquick2.qml", createQtQuick("QtQuick Controls 2", "qrc:///qml/demo-qtquick2.qml",
model, box, initialTab); model, box, initialTab);
} else } else
#endif #endif
createQtQuick("QtQuick", "qrc:///demo.qml", model, box, initialTab); createQtQuick("QtQuick", "qrc:///qml/demo.qml", model, box, initialTab);
#endif #endif
} }
}; };
box->connect(box, &QComboBox::currentTextChanged, box, f); box->connect(box, &QComboBox::currentTextChanged, box, f);
QSvgWidget* logo = new QSvgWidget(":/logo.svg"); QSvgWidget* logo = new QSvgWidget(":/logo.svg");
logo->setFixedSize(logo->renderer()->defaultSize()); logo->setFixedSize(logo->renderer()->defaultSize() / 4);
QWidget* tab = new QWidget; QStatusBar* statusBar = new QStatusBar;
QVBoxLayout *layout = new QVBoxLayout; statusBar->addPermanentWidget(logo);
layout->addWidget(box); statusBar->addPermanentWidget(box);
layout->addWidget(logo); return statusBar;
tab->setLayout(layout);
return tab;
} }
QWidget* createObjectTab(Model* model) { QWidget* createObjectTab(Model* model) {
@ -270,12 +268,8 @@ QWidget* createChartTab(Model* model) {
} }
#endif #endif
void createWidgets(Model* model, const QString& initialStyle, QTabWidget* createTabs(Model* model, QComboBox* box) {
const QString& initialTab) {
QTabWidget* tabs = new QTabWidget(); QTabWidget* tabs = new QTabWidget();
QComboBox* box = createStyleComboBox(model);
tabs->addTab(createStyleTab(model, tabs, box, initialTab), "style");
tabs->addTab(createObjectTab(model), "object"); tabs->addTab(createObjectTab(model), "object");
tabs->addTab(createListTab(model), "list"); tabs->addTab(createListTab(model), "list");
tabs->addTab(createTreeTab(model), "tree"); tabs->addTab(createTreeTab(model), "tree");
@ -287,8 +281,20 @@ void createWidgets(Model* model, const QString& initialStyle,
#ifdef QT_CHARTS_LIB #ifdef QT_CHARTS_LIB
tabs->addTab(createChartTab(model), "chart"); tabs->addTab(createChartTab(model), "chart");
#endif #endif
tabs->setMinimumSize(QSize(500, 500)); return tabs;
tabs->show(); }
void createMainWindow(Model* model, const QString& initialStyle,
const QString& initialTab) {
QMainWindow* main = new QMainWindow();
main->setMinimumSize(QSize(500, 500));
QComboBox* box = createStyleComboBox(model);
QStatusBar* statusBar = createStatusBar(model, main, box, initialTab);
main->setStatusBar(statusBar);
QTabWidget* tabs = createTabs(model, box);
main->setCentralWidget(tabs);
main->show();
box->setCurrentText(initialStyle); box->setCurrentText(initialStyle);
for (int i = 0; i < tabs->count(); ++i) { for (int i = 0; i < tabs->count(); ++i) {
if (tabs->tabText(i) == initialTab) { if (tabs->tabText(i) == initialTab) {
@ -327,14 +333,15 @@ int main (int argc, char *argv[])
parser.process(app); parser.process(app);
Model model; Model model;
model.demo.fibonacci()->setInput(1);
model.demo.fileSystemTree()->setPath("/"); model.demo.fileSystemTree()->setPath("/");
model.sortedFileSystem.setSourceModel(model.demo.fileSystemTree()); model.sortedFileSystem.setSourceModel(model.demo.fileSystemTree());
model.sortedFileSystem.setDynamicSortFilter(true); model.sortedFileSystem.setDynamicSortFilter(true);
model.sortedProcesses.setSourceModel(model.demo.processes()); model.sortedProcesses.setSourceModel(model.demo.processes());
model.sortedProcesses.setDynamicSortFilter(true); model.sortedProcesses.setDynamicSortFilter(true);
createWidgets(&model, parser.value(initialStyleOption), createMainWindow(&model, parser.value(initialStyleOption),
parser.value(initialTabOption)); parser.value(initialTabOption));
return app.exec(); return app.exec();
} }