I've noticed a new DropArea component in Qt5. I'm trying to drag a file from Finder (Mac) but only onEntered method is called.
import QtQuick 2.0
Rectangle {
id: background;
color: "white";
width: 300;
height: 300;
DropArea {
id: dropArea;
anchors.fill: parent;
onEntered: {
background.color = "gray";
drag.accept (Qt.CopyAction);
console.log("onEntered");
}
onDropped: {
console.log ("onDropped");
}
onExited: {
bckground.color = "white";
console.log ("onExited");
}
}
}
and here is window creation code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QQuickView qmlView;
qmlView.setGeometry(0, 200, 600, 400);
qmlView.setResizeMode (QQuickView::SizeRootObjectToView);
qmlView.setSource(QUrl::fromLocalFile("/Users/ivann/Projects/QtGuiTestApp/testView.qml"));
qmlView.show();
return a.exec();
}
Am I missing something?
Seems to be a Mac-specific issue (it wokrs as expected on Linux at least). Filled a bugreport to Nokia: https://bugreports.qt.io/browse/QTBUG-27125
As stated in the link attached by chebum that feature is not supported by QtQuick on any platform at the time of this writing.
Only posting for letting it know to future readers.
QtQuick 5.2 supports drag and drop from external applications. See the example http://qt-project.org/doc/qt-5/qtquick-externaldraganddrop-example.html
Related
I have problems with my QML ScrollViews in a Qt application. I can not avoid the interactive mode, even setting the property to 'false'
For testing, I have the docu QML example loaded in a QQuickView:
main.cpp:
int main(int argc, char *argv[])
{
QtQuickControlsApplication a(argc, argv);
QQuickView* pView = new QQuickView();
pView->setSource(QUrl("qrc:/TestScroll.qml"));
pView->setColor("white");
pView->setHeight(400);
pView->setWidth(600);
pView->show();
return a.exec();
}
TestScroll.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
ScrollView {
width: 200
height: 200
ScrollBar.vertical.interactive: false // Not working
ListView {
model: 20
delegate: ItemDelegate {
text: "Item " + index
}
}
}
What am i doing wrong?
I think I did not explain my problem properly, sorry...
What I need is to avoid the 'bounce' at the end of the scroll view when scrolling using the wheel. When I use the scrollBar for scrolling, I get no bounce at the end of the scrolling screen
Thanks,
Diego
I am building a desktop application using QML with QQuickWidget and QMainWindow, everything looks work fine except to the FileDialog. When I open a window using FileDialog it works flawlessly at first time but in the second time and so on the FileDialog window is rendered behind the main window, preventing the user to choose a file, it is just possible to choose a file after click on the "choose window" (that bring it forward). If the application is in fullscreen mode it is not possible to realize that the FileDialog window is opened.
It just happen when I use QQuickWidget and QMainWindow, if I create a project with QGuiApplication (without QQuickWidget and QMainWindow) I don't have any problems with FileDialog behavior. Some idea how can I make FileDialog work properly with QQuickWidget?
FileDialog code:
/*uncomment ApplicationWindow and comment the rectangle component to right behavior*/
/*
ApplicationWindow{
height: 600
width: 800
*/
Rectangle {
id: rect
visible: true
Button{
id:open
height: 40
onClicked: fileDialog.open()
text: "open dialog"
}
FileDialog {
id: fileDialog
modality: Qt.ApplicationModal
title: "FileDialogTest"
nameFilters: [ "Zip Files (*.zip )", "All files (*)" ]
selectedNameFilter: "All files (*)"
selectFolder: false
onAccepted: {
console.log("Accepted")
}
onRejected: {
console.log("Rejected")
}
}
//}
Main.cpp
int main(int argc, char *argv[])
{
/*##### This block make fileDialog work properly #####*/
/*
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
*/
/*#### This block make openDialog work have weird behavior ####*/
/* Should be commented when the previous block is uncomment */
QApplication app(argc, argv);
QMainWindow mainWindow;
QQuickWidget *quickWidget = new QQuickWidget;
quickWidget->setMinimumSize(800, 600);
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
quickWidget->setSource(QUrl("qrc:/main.qml"));
mainWindow.setCentralWidget(quickWidget);
mainWindow.show();
return app.exec();
}
I made a simple example of my problems it can be download by https://drive.google.com/file/d/1B_qtSZnigrLtDMHS0-84mOrFe5t2ZVIj/view?usp=sharing and can be run on QtCreator to illustrate my problem.
in my QT application for embedded device , i want play a sound on key pressed event of the QML virtualkeyboard . Can I get this event? and How get it?
I already have a class that play sound ( click effect) when a button was clicked that i use in the others qml pages
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
import QtQuick.VirtualKeyboard 2.1
Page{
id: pag
width: 1280
height: 800
background: Rectangle { color: "black"}
TextField {
id: txtName
height: 200
width:200
anchors.horizontalcenter:parent.horizontalCenter
font.family: "Arial
font.pixelSize: 24
placeholderText: "insert your text here"
background: Rectangle {
anchors.fill: parent
color: "transparent"
}
}
InputPanel {
id: virtualkeyboard
width: 0.95*parent.width
anchors.bottom: parent.bottom
}
}
You can create a class Mykeyfilter, it's a QObject class
then in your file .h you declare:
bool eventFilter(QObject *object, QEvent *event);
Then in your Mykeyfilter.cpp file you define eventFilter like this:
bool MykeyFilter::eventFilter(QObject *object, QEvent *event)
{
switch(event->type())
{
case QEvent::KeyPress:
case QEvent::KeyRelease:
{
//////call your sound class here that you want to play/////
qDebug()<<"I have clicked" //For testing
}
default:
break;
// return QObject::eventFilter(object, event);
}
return QObject::eventFilter(object, event);
}
Also add in your main.cpp file:
#include "mytouchfilter.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
app.installEventFilter(new MykeyFilter());
return app.exec();
}
You have two options:
Use the clicked() signal of BaseKey.
Use the soundEffect property of KeyPanel.
Both require having your own style. You can read more about creating your own style here. To quote from there:
A good starting point for creating a new style is to use an existing built-in style as a template and edit it. You can find the built-in styles from the virtual keyboard sources directory src/virtualkeyboard/content/styles. Copy one of the directories containing a built-in style into the Styles directory and rename it to "test". [...]
My cpp application has a QMainWindow derived class, with QQuickView widget in the ui. Inside the view are a number of QML items which accept keyboard input. When an item is clicked, I call forceActiveFocus() on the clicked item. It all works from the time I launch the application, until the time I switch to another window.
If I switch to another application and back, or switch to another window within my application and back, calling forceActiveFocus() has no effect. The items are of a few different types, but here is a sample item:
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
MouseArea {
anchors.fill: textInput
onClicked: {
textInput.forceActiveFocus()
console.log("clicked")
}
}
}
When switching away I see activeFocus logged to the console as false. When I switch back again and click on the item, "clicked" is logged to the console, so the mouse event is being handled. However, onActiveFocusChanged is never called again.
I also tried an implementation with a FocusScope as the parent of the item, got the same behavior, with focus following my click until the point I switch away to some other window and back again.
UPDATE
After reading the comment from #user2436719, I've tried two minimal examples. It is only when using the QQuickView that this problem arises. Here is the QML app using a QML Window with the following main.qrc, which works just fine:
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
The second is a CPP application with a QMainWindow derived class that has a QQuickView widget in the ui. This version exhibits the problem behavior. Here is the main.qrc:
import QtQuick 2.7
import QtQuick.Window 2.2
Rectangle {
anchors.fill: parent
color: "lightblue"
Rectangle {
id: textInputRect
color: "white"
height: 50
width: 150
anchors.centerIn: parent
TextInput {
id: textInput
anchors.fill: parent
inputMethodHints: Qt.ImhFormattedNumbersOnly
onActiveFocusChanged: console.log(activeFocus)
onEditingFinished:
{
}
}
}
}
From the QQuickView version, here is main:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
MainWindow window;
QQuickView* view = new QQuickView;
window.setView(view);
window.show();
return app.exec();
}
And here is how I set the QQuickView in the MainWindow:
void MainWindow::setView(QQuickView *value)
{
view = value;
QWidget *container = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));
ui->verticalLayout->addWidget(container);
}
Okay, this is QTBUG-34414. At the bottom of the comments for that bug a workaround is posted. The posted workaround fixed the problem for me, in the case of switching to other windows of my application, or to other applications. There was still no focus after closing dialogs. Putting this override in my window class fixed the problem for both cases:
bool MyWindow::event(QEvent *event)
{
if (event->type() == QEvent::ActivationChange ||
event->type() == QEvent::WindowUnblocked) {
if(view->isActive()) { //view is pointer to my QQuickView
window()->activateWindow();
return true;
}
}
// handle events that don't match
return QWidget::event(event);
}
This override worked for me with Qt 5.7 on OSX Sierra.
Here's my situation. I'm trying to combine qml with a mostly widget based UI. To do this, I'm using QQuickView with QWidget::createWindowContainer. I can't use QQuickWidget, because I need to convert the window into a native window, and QQuickWidget doesn't like that. But back to the issue.
My problem is that the first time the view is displayed, it takes like half a second to load causing a very obvious flicker. After that I can hide/show the view all I want, it displays immediately. It's only the first time the qml loads. And I'm fairly certain it's the loading of the qml that causes the issue. Because I have two different QQuickViews that get the same qml as their source. But after any one of them loads once, the other has no issues displaying instantly.
I tried to call show() on view early to get it to load in time. But this causes the qml to appear for a brief moment before any of the widgets get displayed.
Has anyone encountered a similar issue? How can I get the QQuickView to behave.
Edit: I'm using Qt 5.4.2, and I can't update to a newer version due to various reasons.
I was going to say that you can use the same approach as in this answer, but it seems that even that is too early to being loading the QML. It's hacky, but the only other thing I can think of is using a very short Timer:
main.cpp:
#include <QtWidgets>
#include <QtQuick>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0) :
QMainWindow(parent)
{
QQuickView *view = new QQuickView();
QWidget *container = QWidget::createWindowContainer(view, this);
container->setFocusPolicy(Qt::TabFocus);
view->rootContext()->setContextProperty("window", view);
view->setSource(QUrl("qrc:/main.qml"));
setCentralWidget(container);
resize(400, 400);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
main.qml:
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.0
Item {
anchors.fill: parent
// Connections {
// target: window
// onAfterSynchronizing: loader.active = true
// }
Timer {
running: true
repeat: true
interval: 50
onTriggered: {
loader.active = true
}
}
Loader {
id: loader
active: false
sourceComponent: Column {
anchors.fill: parent
Repeater {
model: 30000
delegate: Button {
text: index
}
}
}
}
BusyIndicator {
running: loader.status === Loader.Null
anchors.centerIn: parent
}
}
For brevity, I chucked the "heavy" QML into sourceComponent, but you can also use the source property to point to a URL.
BusyIndicator runs its animation on the render thread, so it can continue to spin while the GUI thread is blocked.