QTableView items was draw differently in PyQt 5.8 and 5.9 - python

It happened when I use the following code on win7 32bit,
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
if __name__ == '__main__':
app = QApplication(sys.argv)
# ui = QMainWindow()
path = r'D:\BaiduYunDownload\untitled'
model = QFileSystemModel()
model.setRootPath(path)
table = QTableView()
table.setModel(model)
table.setRootIndex(model.index(path))
# ui.setCentralWidget(table)
table.resize(800, 600)
table.show()
viewOptions = table.viewOptions()
print(table.wordWrap(),
int(viewOptions.textElideMode),
int(viewOptions.decorationAlignment),
int(viewOptions.displayAlignment),
int(viewOptions.features))
app.exec_()
there is only one file with the long name(for test):
A directory model that displays the contents of a default directory is usually constructed with a parent object.txt
in dir D:\BaiduYunDownload\untitled
In PyQt 5.8 (installed via pip3 install pyqt5==5.8)
In PyQt 5.9.1 (installed via pip3 install pyqt5==5.9)
I wonder why the QTableView item in the Name column was draw differently ? I checked with the following property in the code, all returned the same value in both version of PyQt .
print(table.wordWrap(),
int(viewOptions.textElideMode),
int(viewOptions.decorationAlignment),
int(viewOptions.displayAlignment),
int(viewOptions.features))

That appears to be a Qt bug. Check out Qt's bug report here.
One workaround consists in setting font properties via CSS.

Related

Module "material" is not installed

I am running code on a Windows 7 VM with Qt Creator and I am getting a module "material" is not installed error when running my code. It is initialized with Python 3.8 using Pyside6. My Qt Creator is version 4.15.0
This is the QML code:
import QtQuick 2.0
import QtQuick.Controls 2.12
Item {
width: 640
height: 480
visible: true
Rectangle {
id: rectangle
x: 232
y: 220
width: 200
height: 200
color: "#c96565"
}
}
This is the Python script: It is a modified version of one of the example default scripts.
import os
import sys
import urllib.request
import json
from pathlib import Path
import PySide6.QtQml
from PySide6.QtQuick import QQuickView
from PySide6.QtCore import QStringListModel, Qt, QUrl
from PySide6.QtGui import QGuiApplication
if __name__ == '__main__':
#Set up the application window
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
#Load the QML file
qml_file = Path(__file__).parent / "main.qml"
view.setSource(QUrl.fromLocalFile(os.fspath(qml_file.resolve())))
#Show the window
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
#execute and cleanup
app.exec()
del view
I didn't use Qt Quick Control elements in the QMl yet though. Even if I do have a Quick Control elements there the same thing happens. However, if I remove/comment out the import statement for Qt Quick Controls below, the application runs fine. I've tried changing the version number next to quick controls too without success.
UPDATE: It seems that not being able to find the module is a path issue, so I brute forced the path into the qml file by adding this line to the top: import "./Controls.2" as QtQuickControls
And I copied pasted the Controls.2 folder that is nested in the PySide6 folder into the root directory of this project. The error I get now is
The plugin <filepath to qtquickcontrols2plugin.dll> uses incompatible Qt library. <5.15.0> [release] import "./Controls.2" as QtQuickControls
I figured it out: I don't need to brute force the path in; in the .pydevproject file of your python project, make sure you add in the full path to PySide6 because for some reason the system cannot find it without the path.
Something like this:
<pydev_pathproperty name="org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH">
<path>\path\to\your\python\venv\or\folder\Lib\site-packages\PySide6</path>
</pydev_pathproperty>
If that doesn't work, try calling the Material module directly:
import QtQuick.Controls.Material 2.12

QwebEngineView doesn't show anything

I have created a piece of code that show a simple webpage (a bokeh graph saved in an html file). This code is working in Windows 10 at work, but on macos-mojave, using PyQT5.9, with Python 3.6, the opened window don't show anything, and makes python crash.
Could anyone helps ?
Many thanks
import sys
from PyQt5.QtWidgets import (QApplication)
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5 import QtCore
class Principale():
def __init__(self):
self.view = QWebEngineView()
self.view.load(QtCore.QUrl("/Users/moncompte/Desktop/essai.html"))
self.view.show()
# Create a custom font
# ---------------------
app = QApplication(sys.argv)
fenetre=Principale()
sys.exit(app.exec_())

Using virtual keyboard with python3 and Qt5

I'd like to use Qt's virtual keyboard (Qt5.11.1 or newer?) in my python3 (3.6) project on Win10, but I'm stuck.
I have anaconda environment and I'm quite sure the Virtual keyboard is also somewhere in there, because I can find some folders with correct name.
What should the main program look like, besides the obvious, to virtual keyboard pop up when an input widget gets selected?
import sys
from qtpy.QtWidgets import QApplication, QDialog, QVBoxLayout, QSpinBox
class Test(QDialog):
def __init__(self):
super(Test, self).__init__()
layout = QVBoxLayout()
self.setLayout(layout)
for i in range(2):
layout.addWidget(QSpinBox())
if __name__ == '__main__':
import os
os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"
app = QApplication(sys.argv)
dialog = Test()
sys.exit(dialog.exec())
edit: to be clear, i don't want to reinvent or customize the wheel, just use it.

Main Window Icon Not Displayed when Frozen with cx_Freeze

I want to display a custom icon in a PyQt window after freezing the baseline with cx_Freeze. The icon displays fine when the unfrozen script is executed from within the IDE (Spyder, for me). I'm using PyQt5, Python 3.6, and Windows 10. Here is my Python script (IconTest.py) that creates a main window and shows the path to the icon and whether the path exists. The icon file needs to be in the same directory as IconTest.py:
import sys, os
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QIcon
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(200, 300, 600, 100)
if getattr(sys, 'frozen', False): #If frozen with cx_Freeze
self.homePath = os.path.dirname(sys.executable)
else: # Otherwise, if running as a script (e.g., within Spyder)
self.homePath = os.path.dirname(__file__)
self.iconFileName = os.path.join(self.homePath, 'myIcon.ico')
self.setWindowIcon(QIcon(self.iconFileName))
self.setWindowTitle('Icon')
self.label1 = QLabel(self)
self.label2 = QLabel(self)
self.label1.move(10, 20)
self.label2.move(10, 40)
self.label1.setText("Path to icon file: " + str(self.iconFileName))
self.label2.setText("Does file exit? " + str(os.path.exists(self.iconFileName)))
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Here is my result when running the script from within Spyder (unfrozen). As you can see, there is an icon displayed that resembles a stopwatch:
Here is my setup.py for creating the frozen baseline:
from cx_Freeze import setup, Executable
import os, sys
exeDir = os.path.dirname(sys.executable)
platformsPath = os.path.join(exeDir, "Library\\Plugins\\Platforms\\")
iconPath = os.path.join(os.path.dirname(__file__), "myIcon.ico")
exe=Executable(script="IconTest.py", base = "Win32GUI", icon = iconPath)
includes=[iconPath, platformsPath]
excludes=[]
packages=[]
setup(
version = "0.1",
description = "My Icon Demo",
options = {'build_exe': {'excludes':excludes,'packages':packages,'include_files':includes}},
executables = [exe]
)
Here is my result when running the frozen script (the executable in the build directory). As you can see, the stopwatch icon is replaced with a generic windows icon:
Suggestions?
Interesting question and nice minimal example. After some searching I guess it could have to do with PyQt5 missing a plugin/DLL to display .ico image files in the frozen application. See e.g. How to load .ico files in PyQt4 from network.
If this is true, you have 2 options:
Try the same example with a .png file as window icon
If the plugins directory is included in the frozen application but it cannot find it, try to add the following statements
pyqt_dir = os.path.dirname(PyQt5.__file__)
QApplication.addLibraryPath(os.path.join(pyqt_dir, "plugins"))`
before
app = QApplication(sys.argv)
in your main script. See this answer.
If the plugins directory is not included in the frozen application, you need to tell cx_Freeze to include it using the include_files entry of the build_exe option. Either you manage to dynamically let your setup script include it at the place where PyQt5 is looking for it, using a tuple (source_path_to_plugins, destination_path_to_plugins) in include_files, or you tell PyQt5 where to look for it, using QApplication.addLibraryPath.
In your previous question to this issue you actually had an entry to include a Plugins\\Platforms directory in your setup script, maybe you simply need to repair this include. Please note that cx_Freeze version 5.1.1 (current) and 5.1.0 move all packages into a lib subdirectory of the build directory, in contrary to the other versions.
ANSWER: I have been using the Anaconda platform and read in other posts that there are issues between PyInstaller and Anaconda because of the way Anaconda structures its content. Thinking the same issue might exist with cx_Freeze, I installed Python (no Anaconda) on a different machine and froze the script from this new Python installation.
The icon appeared as expected in the frozen script. To make the icon display properly, I made the following changes to the setup.py script:
Removed import sys
Removed the line exeDir = ...
Removed the line platformsPath = ...
Removed platformsPath from the includes = list
I had a similar problem and posted an answer here.
Basically, I have overcome this issue by storing the file in a python byte array and loading it via QPixmap into a QIcon.

PyQt icons missing?

I am new to PyQt and I am learning to make GUIs based on online tutorials I found. One of the examples in the tutorials uses an icon, here is the code from the tutorial:
import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication
from PyQt5.QtGui import QIcon
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.triggered.connect(qApp.quit)
self.toolbar = self.addToolBar('Exit')
self.toolbar.addAction(exitAct)
self.setGeometry(300, 300, 300, 200)
self.setWindowTitle('Toolbar')
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
The output according to the tutorial should be
But for me it's this
As I said, I just started with PyQt and I just installed PyQt through pip
pip install PyQt5
I'm using Python3.6 and PyQt5. Any help is greatly appreciated!
Yes, PyQt5 does come with a list of default icons. You can find them here:
List of PyQt Icons
However, it seems the "exit" icon from the tutorial you refrenced used a local icon downloaded on their computer. You need to download the same icon and name it 'exit24.png' next to your python file.

Categories

Resources