I have set ObjectName to a class in main and want to access this object from another class:
main.cpp
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
ImageProvider *imageProvider = new ImageProvider(&engine,QQmlImageProviderBase::Image,0);
PageBuffer p;
p.setObjectName("Object");
engine.rootContext()->setContextProperty("p",&p);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
engine.addImageProvider("images", imageProvider);
return app.exec();
}
The class where i am trying to access PageBuffer p from:
QImage ImageProvider ::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QQuickWindow *window = qobject_cast<QQuickWindow*>(m_engine->rootObjects()[0]);
PageBuffer *p = window->findChild<PageBuffer *>("Object");
cout<<p->current_box; //error at runtime
QImage e;
e.load("Pic4.jpg");
return e;
}
But i cant seem to access any member of the object PageBuffer, maybe because of pointers, how can can i access the functions from the object p?
You could just introduce a pageBuffer member to ImageProvider:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
ImageProvider *imageProvider = new ImageProvider(&engine,QQmlImageProviderBase::Image,0);
PageBuffer p;
imageProvider->setPageBuffer(p);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
engine.addImageProvider("images", imageProvider);
return app.exec();
}
Then you don't need to search for object children, you can access pageBuffer directly:
QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QQuickWindow *window = qobject_cast<QQuickWindow*>(m_engine->rootObjects()[0]);
PageBuffer *p = pageBuffer();
cout << p->current_box;
QImage e;
e.load("Pic4.jpg");
return e;
}
Related
Whenever the application window is minimized or maximized i want to link that signal with a function.
This is the code.
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
Renderer w(model ); // This is QWidget
w.show();
QObject::connect(&w, &QWindow::windowStateChanged, [&](Qt::WindowState state) {
});
// how will i define the QObject::connect
return application.exec();
}
What would be the parameters for the QObject::connect function ?
You cannot use the connect function to connect to different slots based on the given value. You can however simply call the functions based on the value by checking the value in your lambda.
At least, you could if you had the signal. However, your connect suggests that w is - or inherits - a QWindow. You can obviously only connect to signals your class provides. As your Renderer is a QWidget, you have to check that class.
The documentation of QWidget tells us, that there is no windowStateChanged signal, but it states:
When the window state changes, the widget receives a changeEvent() of type QEvent::WindowStateChange.
So therefor we can create our own signal and connect to that. This can look similar to the following working example:
#ifndef RENDERER_H
#define RENDERER_H
#include <QWidget>
#include <QEvent>
class Renderer : public QWidget {
Q_OBJECT
signals:
void stateChanged(bool isMaximized);
protected:
void changeEvent(QEvent *e)
{
if(e->type() == QEvent::WindowStateChange) {
emit stateChanged(windowState() & ~Qt::WindowMaximized);
}
QWidget::changeEvent(e);
}
};
#endif // RENDERER_H
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
Renderer w; // This is QWidget
w.show();
QObject::connect(&w, &Renderer::stateChanged, [&](bool maximized) {
qDebug() << "Maximized?" << maximized;
});
return application.exec();
}
I was able to solve by using QApplication::focusWindow()
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
Renderer w; // This is QWidget
w.show();
QObject::connect(QApplication::focusWindow(), &Renderer::stateChanged, [&](bool maximized) {
qDebug() << "Maximized?" << maximized;
});
return application.exec();
}
The problem I have in my code is, once the QML engine uplouded the QProcess stop!! Is it possible to let QProcess run while the QMLis already in operation!
the idea is: I want the user to be able to interact with only one specific mouse and one keyboard and to continually check this condition!
Can some one check what is the problem here?
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
bool scanForDevices=0;
USBdeviceID *usbdeviceid =new USBdeviceID();
engine.rootContext()->setContextProperty("USBdeviceID", usbdeviceid);
QProcess OProcess;
QString Command; //Contains the command to be execute
Command = "lsusb";
while (1)
{
OProcess.start(Command,QIODevice::ReadOnly); //Starts execution of command
OProcess.waitForFinished(); //Waits for execution to complete
QString StdOut = OProcess.readAllStandardOutput(); //Reads standard output
QString StdError = OProcess.readAllStandardError(); //Reads standard error
cout<<"\n Printing the standard output..........\n";
cout<<endl<<StdOut.toStdString();
bool mouse1 = StdOut.contains("ID 046d:c03e");
bool keyBoard1 = StdOut.contains("ID 413c:1003");
if (mouse1 ==1 && keyBoard1==1)
{
// start main program
// revoke A signal to tell QML the correct devices are connected
usbdeviceid->setMouse1Detected(1);
usbdeviceid->setkeyBoard1Detected(1);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
}
}
}
It is not necessary to create infinite loops in Qt, instead the most elegant thing is to use the signals.
#include <QGuiApplication>
#include <QProcess>
#include <QQmlApplicationEngine>
class LSUSB: public QObject
{
Q_OBJECT
public:
LSUSB(const QStringList & ids, QObject *parent=nullptr): QObject(parent), status(false), ids(ids)
{
QString command = "lsusb";
connect(&process, &QProcess::readyReadStandardOutput, this, &LSUSB::onReadyReadStandardOutput);
connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &LSUSB::onFinished);
process.setProgram(command);
process.start();
}
Q_SIGNALS:
void isLoaded();
private Q_SLOTS:
void onReadyReadStandardOutput(){
QString stdout = process.readAllStandardOutput();
status = true;
for(const QString & id: ids){
status &= stdout.contains(id);
}
if(status){
process.kill();
Q_EMIT isLoaded();
}
}
void onFinished(){
if(!status)
process.start();
}
private:
QProcess process;
bool status;
QStringList ids;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
LSUSB lsusb({"ID 046d:c03e", "ID 413c:1003"});
USBdeviceID usbdeviceid;
QObject::connect(&lsusb, &LSUSB::isLoaded, [&engine, &usbdeviceid](){
usbdeviceid.setMouse1Detected(1);
usbdeviceid.setkeyBoard1Detected(1);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
QCoreApplication::exit(-1);
});
return app.exec();
}
#include "main.moc"
I'm going to deploy the qtvirtualkeyboard in my widget-based application like so:
#include <QtWidgets>
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
QMainWindow window;
QLineEdit input(&window);
input.move(250, 250);
window.show();
return app.exec();
}
But the only issue is that the virtual keyboard input panel hides the underlying widgets and cover them!
How should I achieve this?
Is there any document or solution for widgets-based applications?
you just need to add this line in main.cpp
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
and will work Virtual Keyboard in Qtwidgets))
Finally got the solution!
You just need to call QGuiApplication::inputMethod() to get the application-wide Qt input method and then call QInputMethod::keyboardRectangle() and QInputMethod::isVisible() to get input method properties then remain a calculation based on your widget position and keyboard coordinate, here is a full-working sample to share:
lineedit.h:
class LineEdit :public QLineEdit {
Q_OBJECT
public:
LineEdit(QWidget *parent = nullptr);
LineEdit(const QString&, QWidget *parent = nullptr);
protected:
bool event(QEvent*) override;
private:
bool _moved = false;
int _lastDiff = 0;
};
lineedit.cpp:
LineEdit::LineEdit(QWidget *parent) :QLineEdit(parent) {
setAttribute(Qt::WA_InputMethodEnabled, true);
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhDigitsOnly);
}
LineEdit::LineEdit(const QString& txt, QWidget *parent) : QLineEdit(txt, parent) {
setAttribute(Qt::WA_InputMethodEnabled, true);
setInputMethodHints(inputMethodHints() | Qt::InputMethodHint::ImhDigitsOnly);
}
bool LineEdit::event(QEvent* e) {
const auto keyboard_rect = QGuiApplication::inputMethod()->keyboardRectangle();
const auto keyboard_visible = QGuiApplication::inputMethod()->isVisible();
const auto global_y = QWidget::mapToGlobal(rect().topLeft()).y() + height();
const auto k_global_y = keyboard_rect.topLeft().y();
const auto diff = k_global_y - global_y;
const auto need_to_move = diff < 0;
/* move main widget */
if (keyboard_visible && !_moved && need_to_move) {
_moved = true;
_lastDiff = diff;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() - qAbs(_lastDiff));
}
/* roll back */
if (!keyboard_visible && _moved) {
_moved = false;
const auto g = parentWidget()->frameGeometry();
parentWidget()->move(g.x(), g.y() + qAbs(_lastDiff));
}
return QLineEdit::event(e);
}
main.cpp:
#include <QtWidgets>
#define W 1024
#define H 768
int main(int argc, char *argv[]) {
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QApplication app(argc, argv);
QMainWindow window(nullptr, Qt::FramelessWindowHint);
LineEdit lineedit1(&window);
lineedit1.move(100, 450);
LineEdit lineedit2(&window);
lineedit2.move(100, 100);
window.resize(W, H);
window.show();
return app.exec();
}
results:
I have a QListWidget which is used in iconMode as the viewMode. When I set an QIcon and the text for a QListWidgetItem, icon is showed on top of the text. If I use the QlistWidget in listMode as the viewMode, icon is shown at the left side of the text. How to show the icon at the left side of the text when the QListWidget is in iconMode ?
I tried setTextAlignment(Qt::AlignRight) for QLIstWidgetItems. But it didn't work.
The decorationPosition property of QStyleOptionViewItem determines the position of the icon, so the solution is to modify those properties:
Override viewOptions() method of QListWidget:
#include <QtWidgets>
class ListWidget: public QListWidget
{
public:
using QListWidget::QListWidget;
protected:
QStyleOptionViewItem viewOptions() const override{
QStyleOptionViewItem option = QListWidget::viewOptions();
option.decorationPosition = QStyleOptionViewItem::Left;
return option;
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ListWidget w;
w.setViewMode(QListView::IconMode);
for (QStyle::StandardPixmap sp: {
QStyle::SP_ArrowBack,
QStyle::SP_ArrowDown,
QStyle::SP_ArrowForward,
QStyle::SP_ArrowLeft,
QStyle::SP_ArrowRight,
QStyle::SP_ArrowUp})
{
QIcon icon = QApplication::style()->standardPixmap(sp);
QListWidgetItem *it = new QListWidgetItem("foo");
it->setIcon(icon);
w.addItem(it);
}
w.show();
return a.exec();
}
Override initStyleOption() method of QStyledItemDelegate
#include <QtWidgets>
class StyledItemDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
protected:
void initStyleOption(QStyleOptionViewItem *option,
const QModelIndex &index) const override
{
QStyledItemDelegate::initStyleOption(option, index);
option->decorationPosition = QStyleOptionViewItem::Left;
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QListWidget w;
w.setViewMode(QListView::IconMode);
StyledItemDelegate *delegate = new StyledItemDelegate(&w);
w.setItemDelegate(delegate);
for (QStyle::StandardPixmap sp: {
QStyle::SP_ArrowBack,
QStyle::SP_ArrowDown,
QStyle::SP_ArrowForward,
QStyle::SP_ArrowLeft,
QStyle::SP_ArrowRight,
QStyle::SP_ArrowUp})
{
QIcon icon = QApplication::style()->standardPixmap(sp);
QListWidgetItem *it = new QListWidgetItem("foo");
it->setIcon(icon);
w.addItem(it);
}
w.show();
return a.exec();
}
i want to remove the icon on the top left of a qt application. here is my main.cpp code
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
Receive receive;
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
// setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
QObject::connect(window,SIGNAL(sendUrltoC(QUrl)),&receive,SLOT(getText(QUrl)));
return app.exec();
}
if i uncomment the commented part it gives me an error. what should i do?