CMake complains about not finding autouic file - qt

I am trying to make a 'HelloWorld' in subdirectories, using automoc and autouic.
I have a main directory with
cmake_minimum_required(VERSION 3.1.0)
project(helloworld)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
find_package(Qt5 COMPONENTS Widgets REQUIRED)
add_subdirectory(main)
add_subdirectory(QtGUI)
and in subdirectory main
add_executable(helloworld
main.cpp
)
include_directories(
include
../QtGUI/include
)
target_link_libraries(helloworld libQtGUI )
and
#include <qapplication.h>
#include <qpushbutton.h>
#include "dialog.h"
int main( int argc, char **argv )
{
QApplication a( argc, argv );
Dialog w;
w.show();
return a.exec();
}
In file QtGUI/dialog.cpp
#include "forms/ui_dialog.h"
#include "dialog.h"
#include "dialog.moc"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
in file QtGUI/CMakeLists.txt
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
#set(AUTOUIC_SEARCH_PATHS forms)
file(GLOB_RECURSE QOBJECT_SOURCES
dialog.cpp
)
include_directories(
${Qt5Widgets_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}
include
forms
)
ADD_LIBRARY(libQtGUI ${QOBJECT_SOURCES} )
file(GLOB_RECURSE HEADERS_TO_MOC include/ *.h)
qt5_wrap_cpp(PROCESSED_MOCS
${HEADERS_TO_MOC}
TARGET libQtGUI
OPTIONS --no-notes) # Don't display a note for the headers which don't produce a moc_*.cpp
target_sources(libQtGUI PRIVATE ${PROCESSED_MOCS}) # This adds generated moc cpps to target
# Use the Widgets module from Qt 5.
target_link_libraries(libQtGUI Qt5::Widgets )
set_target_properties(libQtGUI PROPERTIES OUTPUT_NAME QtGUI
)
target_include_directories(libQtGUI PUBLIC
${Qt5Widgets_INCLUDE_DIRS}
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)
and QtGUI/include/dialog.h is
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QString>
//#include "mythread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
virtual ~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
Without using AUTOUIC (i.e when I generate ui_dialog.h manually, it compiles and runs, but I receive a
The file includes the moc file "dialog.moc", but does not contain a Q_OBJECT, Q_GADGET or Q_NAMESPACE macro.
warning. When I attempt to use AUTOUIC, I receive an error:
fatal error: ui_dialog.h: No such file or directory
#include "ui_dialog.h"
What do I wrong?
According to the docs,
"If a preprocessor #include directive is found which matches <path>ui_<basename>.h, and a <basename>.ui file exists, then uic will be executed to generate the appropriate file. "
I expected that forms/ui_dialog.h will be generated.
(I have dialog.ui file both in QtGUI and QtGUI/forms)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="StartButton">
<property name="geometry">
<rect>
<x>150</x>
<y>60</y>
<width>89</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QPushButton" name="StopButton">
<property name="geometry">
<rect>
<x>280</x>
<y>60</y>
<width>89</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Stop</string>
</property>
</widget>
<widget class="QTextBrowser" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>121</width>
<height>31</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

The ui file is generated in ${CMAKE_CURRENT_BINARY_DIR}, not ${CMAKE_BINARY_DIR} - so include this path and see if it works.

I don't see reason to have duplicate UI files; looks like the first one is used to generate but second one is expected to exists. Then, to solve
UI issue, remove dialog.ui from QtGUI folder (keep only UI file in 'forms' subfolder)
the warning is OK because you don't have these reserved words in CPP file i.e. there is nothing to generate from your CPP; the referred documentation is in 'Source file processing' section. Just remove that 'dialog.moc' include. And it will work as expected.
Now it compiles and run without warnings/issues.

Related

Qt ui file - xml order - QGridLayout row order leads to large commit differences

Sometimes when using QT Designer, in the resulting ui file xml format, the order of the rows is not respected (row="11" is presented before row="0").
I understand that functionally it has zero impact on the compiled code. I have two concerns about this behaviour:
a) the differences generated for "small modifications" are big, this reduces my capacity to review a PR and increases the probability of an oversight.
b) I sometimes edit ui files in text mode from the terminal. Having the rows order sorted is desirable.
Concern a) is by far more important to me.
Example is this PR, which concerns the removal of three rows.
Because the external link may be removed, here I include a relevant excerpt showing the issue:
<layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_17">
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_43">
<property name="minimumSize">
<size>
<width>182</width>
## -31,27 +31,7 ##
</size>
</property>
<property name="text">
- <string>Default edge color</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="Gui::PrefColorButton" name="SketchEdgeColor">
- <property name="toolTip">
- <string>Color of edges</string>
- </property>
- <property name="color">
- <color>
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="prefEntry" stdset="0">
- <cstring>SketchEdgeColor</cstring>
- </property>
- <property name="prefPath" stdset="0">
- <cstring>View</cstring>
+ <string>Fully constrained edit internal alignment edge color</string>
</property>
</widget>
</item>
## -68,61 +48,28 ##
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="Gui::PrefColorButton" name="SketchVertexColor">
- <property name="toolTip">
- <string>Color of vertices</string>
- </property>
- <property name="color">
- <color>
- <red>255</red>
- <green>255</green>
- <blue>255</blue>
- </color>
- </property>
- <property name="prefEntry" stdset="0">
- <cstring>SketchVertexColor</cstring>
- </property>
- <property name="prefPath" stdset="0">
- <cstring>View</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_6">
- <property name="minimumSize">
- <size>
- <width>182</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>Making line color</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="Gui::PrefColorButton" name="CreateLineColor">
+ <item row="6" column="1">
+ <widget class="Gui::PrefColorButton" name="InternalAlignedGeoColor">
<property name="toolTip">
- <string>Color used while new sketch elements are created</string>
+ <string>Color of edges of internal alignment geometry</string>
</property>
<property name="color">
<color>
- <red>204</red>
- <green>204</green>
- <blue>204</blue>
+ <red>178</red>
+ <green>178</green>
+ <blue>127</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
- <cstring>CreateLineColor</cstring>
+ <cstring>InternalAlignedGeoColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label">
In some cases even the second column of the same row () appears in the source after the first column ().
I do understand that order is not important from a functional point of view and that there is no functional requirement that rows and cols are sorted.
My question is: Is there any reasonable way (for example an option or plugin for Qt Designer, or an alternative, or a tool for reformatting an ui file) so that the columns are sorted in the ui file, leading to reasonable to review differences?
Thanks in advance for your time,
abdullah
This python script will sort the children item of any QGridLayout widget in a Qt UI file by row-column order.
#!/usr/bin/env python
# encoding: utf-8
from __future__ import print_function
import logging
from lxml import etree
# Inspired from here: https://stackoverflow.com/a/46128043
def sort_children(node, klass, key):
""" Sort children along tag and given attribute.
if attr is None, sort along all attributes"""
if not isinstance(node.tag, str): # PYTHON 2: use basestring instead
# not a TAG, it is comment or DATA
# no need to sort
return
if node.get('class') == klass:
# sort child along attr
node[:] = sorted(node, key=key)
else:
# and recurse
for child in node:
sort_children(child, klass, key)
def sort(unsorted_file, sorted_file, klass, key):
"""Sort unsorted xml file and save to sorted_file"""
tree = etree.parse(unsorted_file)
root = tree.getroot()
sort_children(root, klass, key)
sorted_unicode = etree.tostring(root,
pretty_print=True,
encoding='unicode')
with open(sorted_file, 'w') as output_fp:
output_fp.write('<?xml version="1.0" encoding="UTF-8"?>\n')
output_fp.write('%s' % sorted_unicode)
logging.info('written sorted file %s', sorted_unicode)
filename = "Path_to_unsorted_QML_file.ui"
filename_out = "Path_to_sorted_QML_file.ui"
def row_col_key(node):
"""Return the sorting key of an xml node"""
row = node.get('row') if node.get('row') else -1
col = node.get('column') if node.get('column') else -1
return '{:04d}{:04d}'.format(int(row), int(col))
sort(filename, filename_out, "QGridLayout", row_col_key)

Error while try to add splash screen to Xamarin forms -Xamarin Android

I am trying to create a splash screen to my app.
I am using Xamarin forms, and I currently testing only in Android
However I am receiving this 2 errors
1)Failed to generate resource table for split '' "Failed to generate resource table for split ''".
Severity Cod'android:windowBackground' with value '#drawble/splashscreen'.
will appreciate any help to solve this issue
thanks.
here is my styles.xml:
<resources>
<style name="Theme.splash" parent="android:Theme">
<item name="android:windowBackground">#drawble/splashscreen</item>
<item name="android:windowNoTitle">true</item>
</style>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--If you are using revision 22.1 please use just windowNoTitle. Without
android:-->
<item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar-->
<item name="windowActionBar">false</item>
<!-- Set theme colors from
http://www.google.com/design/spec/style/color.html#color-color-palette -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#1976D2</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#FF4081</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<item name="windowActionModeOverlay">true</item>
<item name="android:datePickerDialogTheme">#style/AppCompatDialogStyle</item>
</style>
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">#FF4081</item>
</style>
</resources>
and here is the code I added to Activity:
[Activity(Label = "SplashScreen", MainLauncher=true, NoHistory=true, Theme = "#style/Theme.splash")]
public class SplashScreen : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
StartActivity(typeof(MainActivity));
}
}
and this is the main acitivity:
[Activity(Label = "RegestrationAppComp", Icon = "#drawable/icon", Theme = "#style/MainTheme", MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
When you create your splashscreen.xml file, you must change its properties. I've followed these steps:
Right click the splashscreen.xml file and select Properties, a window will show up at the bottom.
On the field Build Action, change the value to AndroidResource
On the field Custom Tool, write MSBuild:UpdateGeneratedFiles (or copy what's written on other files above in the same folder or from the values/styles.xml file.
Please add your image(in your case image file name is "splashscreen") in drawable folder using visual studio. For this, you have to right click on "Drawable" folder -> click on "Add Existing Item" -> select your image from your laptop/PC drive location and click on "Add".. Thats it !!! Now you can build and deploy solution again..

Lumen/Elixir - File to import not found or unreadable

I need to setup sass in Lumen project, from the sass made in kitchen sink. It is my first time setting it up, so I am wondering how to setup a gulpfile.js for it?
I have installed node_modules by running npm install, and I have also installed laravel elixir.
I have put my folder/files structure looks like this:
resources/assets/img
/js/app.js
/sass/_settings.scss
app.scss
My gulpfile.js looks like this:
var elixir = require('laravel-elixir');
/*
|--------------------------------------------------------------------------
| Elixir Asset Management
|--------------------------------------------------------------------------
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Sass
| file for our application, as well as publishing vendor resources.
|
*/
elixir(function(mix) {
mix.sass('app.scss');
});
But when I run gulp I get errors for all import and includes in my scss files:
This is how my scss files look like:
app.scss
#import "settings";
#import "foundation";
#import "motion-ui";
#include foundation-flex-grid;
#include foundation-global-styles;
#include foundation-typography;
#include foundation-button;
#include foundation-forms;
#include foundation-visibility-classes;
#include foundation-float-classes;
#include foundation-flex-classes;
// #include foundation-accordion;
// #include foundation-accordion-menu;
// #include foundation-badge;
// #include foundation-breadcrumbs;
// #include foundation-button-group;
// #include foundation-callout;
// #include foundation-close-button;
// #include foundation-drilldown-menu;
// #include foundation-dropdown;
// #include foundation-dropdown-menu;
// #include foundation-flex-video;
// #include foundation-label;
// #include foundation-media-object;
// #include foundation-menu;
// #include foundation-off-canvas;
// #include foundation-orbit;
// #include foundation-pagination;
// #include foundation-progress-bar;
// #include foundation-slider;
// #include foundation-sticky;
// #include foundation-reveal;
// #include foundation-switch;
// #include foundation-table;
// #include foundation-tabs;
// #include foundation-thumbnail;
// #include foundation-title-bar;
// #include foundation-tooltip;
// #include foundation-top-bar;
#include motion-ui-transitions;
#include motion-ui-animations;
And my _setttings.scss has this line, for which I get an error:
#import 'util/util';
Error:
{ [Error: resources/assets/sass/_settings.scss Error: File to import
not found or unreadable: util/util
Parent style sheet: /Users/markodraksic/Projects/Quiz-landing-page/resources/assets/sass/_settings.scss
on line 42 of resources/assets/sass/_settings.scss
#import 'util/util';
I reproduced your error and found the solution here.
You can try to copy the package to your resources.
Add the copy method to your gulpfile:
elixir(function(mix) {
mix.copy('node_modules/foundation-sites/scss', 'resources/assets/sass')
.sass('app.scss');
});
Another option is to add an include path (which I couldn't get to work).

Qt Quick does not translate components loaded via Loader

Situation:
Writing a Qt Quick application for embedded Linux system, want to use Qt translation mechnanism. Application shall select language on command coming in via RS232, currently hardcoded to "de" on a system set up for english language. Application loads various masks on command from RS232.
Problem:
Qt Quick translates only the main page (main.qml), but not the pages loaded via the Qt Loader (DEMO.ui.qml). Texts from main.qml are displayed in german, texts from DEMO.ui.qml are displayed untranslated.
I've added a "XX" prefix to all english translations (qml.en.ts), that also does not appear on the screen. So neither english nor german translations are loaded for pages loaded via the Qt Loader.
Clean build after lupdate, lrelease does not help. rm -rf build-$appname-*, build does not help.
Code:
application.cpp:
xlat=new QTranslator();
if (xlat->load(QLocale("de"), "qml", ".", ":/qml/i18n/", ".qm")) {
qDebug()<<"load translator ok";
bool ok=installTranslator(xlat);
//...
} // else error message
// ...
viewer->setSource(QUrl("qrc:/qml/main.qml"));
viewer->showFullScreen();
// ...
main.qml:
import QtQuick 2.0
Rectangle {
Text {
id: loadingMsg
text: qsTr("Loading ...")
// ...
}
Loader {
// ...
source: ""
function loadMask(aMaskId) {
// ...
setSource(gui.urlForMask(aMaskId));
}
}
// ...
}
components/SimpleButton.qml:
import QtQuick 2.0
// ...
Rectangle {
Text {
id: label
text: ""
// ...
}
property alias text: label.text
}
masks/DEMO.ui.qml:
import QtQuick 2.0
import "../components"
//...
SimpleButton {
//...
text: qsTr("Vent.")
}
//...
qml.de.ts:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="de_DE">
<!-- ... -->
<context>
<name>DEMO</name>
<!-- ... --->
<message>
<source>Vent.</source>
<translation>Belüften</translation>
</message>
</context>
<context>
<name>main</name>
<message>
<source>Loading ...</source>
<translation>Lade ...</translation>
</message>
<!-- ... -->
</context>
Renaming DEMO.ui.qml to DEMO.qml did the trick. I guess that the Linguist tools (lupdate, lrelease) and the Qt runtime environment have different ideas of how to convert a filename to a context name.

Load qmldir from QRC file

I'm trying to use the QML-material library in a Qt Quick Application.
But when I try to use the import code it says
module "Material" is not installed`
import Material 0.1
I did also try this but that seems not to work:
import "modules/Material" as Material
qml.qrc looks like this, all qmldir files are listed:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>modules/Material/qmldir</file>
<file>modules/Material/Extras/qmldir</file>
<file>modules/Material/ListItems/qmldir</file>
<file>modules/QtQuick/Controls/Styles/Material/qmldir</file>
</qresource>
</RCC>
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
Is there something I'm missing or is it not possible to use qmldir in qrc file?
You need to add to the import path the folder where the modules are located.
In this case it's qrc:/modules/.
Example:
engine.addImportPath( "qrc:///modules" );
For a module to work you need to have access to the qmldir file, but also all the files referenced in it. So you need to add all the files of the library to the the qrc.

Resources