PyQt5 - Update an Image in QML - image

I have been looking for a way to update images on my QML UI from my PyQt code. The closest answer I could find was from Grecko Update ImageView in QML
// Code from Stackoverflow Link
// MyImage.qml
Image {
cache: false
function reload() {
var tmpSource = source;
source = "";
source = tmpSource;
}
}
I would like to apply that solution (or any solution) to my project. Below is some sample code that is similar to my implementation.
#test.py
import sys
from PyQt5.QtCore import QObject, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtQml import QQmlApplicationEngine
if __name__ == '__main__':
myApp = QApplication(sys.argv)
engine = QQmlApplicationEngine()
context = engine.rootContext()
context.setContextProperty("main", engine)
engine.load('main.qml')
win = engine.rootObjects()[0]
image = win.findChild(QObject, "myimage")
#What do with the image here?
win.show()
sys.exit(myApp.exec_())
Here is the QML code.
//test.qml
Image {
id: image1
objectName: "myimage"
x: 384
y: 403
width: 100
height: 100
source: ""
}
I am still fairly new to PyQT5 and QML so if someone has a basic example that shows how I can implement this or can edit my basic example, it would be greatly appreciated.
Thank you :)

If you want to reload all images via your MyImage type, then one option is to use the setContextProperty() mechanism to expose an Python object with a signal and use that signal in MyImage.qml to trigger the reload() function.
In Python:
reloader = ObjectWithAReloadSignal()
context.setContextProperty("_reloader", reloader);
in MyImage.qml
Image {
id: image
void reload() { ... }
Connections {
target: _reloader
onReloadImages: image.reload()
}
}
The assumption here is that the ObjectWithAReloadSignal has a signal called reloadImages() which ti emits when QML should trigger the reload.

Related

How to handle system Dark mode in QML

I'm using QML + Python to create a multi-platform application. Facing a challenge with handling System Dark Mode (not sure if it applies to Windows, but I'm currently using a Mac).
For now I do set Dark / Light mode manually, using property. Is there any way I can detect user's mode and set this value to my property? Or are there any other possible solutions?
import QtCore
import QtQuick
import QtQuick.Controls
import QtQuick.Dialogs
ApplicationWindow {
width: 640
height: 480
visible: true
property bool darkMode: false
Text {
id: textField
color: {
switch (darkMode) {
case true:
"white";
break;
case false:
"black";
break;
}
}
}
}

I am searching for a Flutter package which can find the barcode of a .pdf file

I am trying to build an application on Windows, which i pick (.pdf) files that contain a barcode on them.
I want to find and extract the barcode info and put it on a list.
I need a package that it can make it happen. A package except https://pub.dev/packages/flutter_barcode_sdk because it has an annually cost for its licence.
I spent some time writing this for you and I made it using two different packages.
This one is able to read barcodes from camera and files
scan: 1.6.0
But I could not make it read PDFs, so I installed another package to render images from PDF files.
native_pdf_renderer: 3.1.0
This package is also required:
path_provider: ^2.0.11
This is the code that worked fine for me:
import 'dart:async';
import 'dart:io';
import 'package:native_pdf_renderer/native_pdf_renderer.dart';
import 'package:path_provider/path_provider.dart';
import 'package:scan/scan.dart';
Future<void> readBarcodeFromPDF(String assetPath) async {
PdfDocument pdf = await PdfDocument.openAsset(assetPath);
for (var pageIndex = 0; pageIndex < pdf.pagesCount; pageIndex++) {
final page = await pdf.getPage(pageIndex);
final image = await page.render(width: 2048, height: 2048);
if (image != null) {
final byteData = image.bytes;
final file = File('${(await getTemporaryDirectory()).path}/barcodes');
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
String? barcode = await Scan.parse(file.path);
if (barcode == null) {
print("barcode not found in page $pageIndex");
} else {
print("Barcode Found: $barcode in page $pageIndex");
}
}
}
}

How to turn window background black on showing modal view in nativescript

As shown in the image 1 below, when the modal view on ios 13 shows up, the default background is black. But on nativescript, the default background is white as shown in the image 2. How to achieve the image 1 kind of background (black) using nativescript core? I tried changing the color of status bar but that actually changes the color of the top page portion that's partially visible in the images. I tried to define background-color on Frame css, but didn't work. Any suggestions? Thanks in advance.
Image 1:
Image 2:
The modal view options:
const option: ShowModalOptions = {
context: { selectedAccount: account },
closeCallback: (a, b, c, action) => {
//some code
},
fullscreen: false
};
mainView.showModal("./modal-add-page", option);
You have to set the background color of window on iOS.
Update: Nativescript 7
import * as app form "#nativescript/core/application";
import { Color } from "#nativescript/core/color";
import { isIOS } from '#nativescript/core';
if (isIOS) {
if (app.hasLaunched) {
app.ios.window.backgroundColor = new Color("black").ios;
} else {
app.on("launch", _ => app.ios.window.backgroundColor = new Color("black").ios)
}
}
Older versions:
import * as app form "tns-core-modules/application";
import { Color } from "tns-core-modules/color";
// You must run it once application is initiated
app.ios.window.backgroundColor = new Color("black").ios;

Haxe Type Not Found

I'm trying to run the most basic Haxe program but keep getting errors.
The Main.hx file looks like this:
package;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.Lib;
import flixel.FlxGame;
import flixel.FlxState;
class Main extends Sprite {
var gameWidth:Int = 640; // Width of the game in pixels (might be less / more in actual pixels depending on your zoom).
var gameHeight:Int = 480; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom).
var initialState:Class<FlxState> = MenuState; // The FlxState the game starts with.
var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions.
var framerate:Int = 60; // How many frames per second the game should run at.
var skipSplash:Bool = false; // Whether to skip the flixel splash screen that appears in release mode.
var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets
// You can pretty much ignore everything from here on - your code should go in your states.
public static function main():Void
{
Lib.current.addChild(new Main());
}
public function new()
{
super();
if (stage != null)
{
init();
}
else
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(?E:Event):Void
{
if (hasEventListener(Event.ADDED_TO_STAGE))
{
removeEventListener(Event.ADDED_TO_STAGE, init);
}
setupGame();
}
private function setupGame():Void
{
var stageWidth:Int = Lib.current.stage.stageWidth;
var stageHeight:Int = Lib.current.stage.stageHeight;
if (zoom == -1)
{
var ratioX:Float = stageWidth / gameWidth;
var ratioY:Float = stageHeight / gameHeight;
zoom = Math.min(ratioX, ratioY);
gameWidth = Math.ceil(stageWidth / zoom);
gameHeight = Math.ceil(stageHeight / zoom);
}
addChild(new FlxGame(gameWidth, gameHeight, initialState, zoom, framerate, framerate, skipSplash, startFullscreen));
}
}
Just the generic template file. When I run it in Terminal (running Mac OS X El Capitan), I get this error:
Main.hx:8: characters 7-21 : Type not found : flixel.FlxGame
Haven't had problems with the installations or anything and I am new to Haxe so I don't know where to start. Any ideas?
Thanks :)
Did you add the library when you try to run your game ?
You can do that by using the command line haxe -lib flixel -main Main ....
Or by writting an hxml file containing all your CLI arguments :
-lib flixel
-main Main
Update after #Gama11 comment :
HaxeFlixel used the OpenFL format for the compilation information (see http://www.openfl.org/documentation/projects/project-files/xml-format/).
So you should include include flixel library using : <haxelib name="flixel" />in your Project.xml file.

Is possible to put an image instead of a button, and make it clickable?

Is possible to put an Image into a GUI Application and make it clickable?
I used to make a button like this:
img = QPixmap(15, 15)
img.fill(Qt.grey)
button = QPushButton(QIcon(img))
button.clicked.connect(self.button_click)
Link http://imagizer.imageshack.us/v2/800x600q90/834/kaqc.png
But I'd prefer to use an image, instead of having a button with an icon..
I had the same requirement and solved it by subclassing QLabel, as yshurik suggests. The amount of additional code is very limited. Here is a working implementation:
class CClickableLabel : public QLabel
{
Q_OBJECT
public:
CClickableLabel(QString text, QWidget *parent = 0) : QLabel(text, parent) {}
~CClickableLabel() {}
signals:
void clicked();
protected:
void mousePressEvent(QMouseEvent *event) { emit clicked(); }
};
Create a instance CClickableLabel, use setPixmap() to set the image and listen to the clicked() signal. That should do the trick.
Here's simple demo script that shows how to make a grid of clickable labels:
from random import shuffle
from PySide import QtCore, QtGui
class ClickableLabel(QtGui.QLabel):
clicked = QtCore.Signal(str)
def __init__(self, width, height, color):
super(ClickableLabel, self).__init__()
pixmap = QtGui.QPixmap(width, height)
pixmap.fill(QtGui.QColor(color))
self.setPixmap(pixmap)
self.setObjectName(color)
def mousePressEvent(self, event):
self.clicked.emit(self.objectName())
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QGridLayout(self)
colors = 'red green blue orange purple yellow'.split()
for row in range(len(colors)):
shuffle(colors)
for column, color in enumerate(colors):
label = ClickableLabel(25, 25, color)
label.clicked.connect(self.handleLabelClicked)
layout.addWidget(label, row, column)
def handleLabelClicked(self, name):
print('"%s" clicked' % name)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 200, 200)
window.show()
sys.exit(app.exec_())
I guess the fast solution is subclass QLabel, use setPixmap() to put image on and reimplement mouseEvent() to submit signal clicked() on press/release event. As it is python (PyQt/PySide) then it should be just few lines. Usually I use such approach when need some graphics clickable.
Buttons are style able, and you can put images on them.

Resources