marcelotduarte / cx_Freeze

cx_Freeze creates standalone executables from Python scripts, with the same performance, is cross-platform and should work on any platform that Python itself works on.
https://marcelotduarte.github.io/cx_Freeze/
Other
1.32k stars 217 forks source link

Version 7.2.0 with Pyside6 6.7.0 #2560

Open licher255 opened 2 weeks ago

licher255 commented 2 weeks ago

Bug Report: cx-freeze 7.2.0 Cannot Build Executable for PySide6 Project

Environment

Problem Description

I encountered an issue when building a PySide6 project into an executable using cx-freeze 7.2.0. After building, the executable cannot be run, and I receive the following error message:

main.qml module "QtQuick.Window" is not installed

However, when I use cx-freeze version 7.1.1 with the exact same setup, the executable is successfully created and runs as expected. The only noticeable difference is that the executable built with cx-freeze 7.1.1 is significantly larger (around 800MB), while the one built with 7.2.0 is only 388MB.

Steps to Reproduce

  1. Create a PySide6 project and try to build it into an executable using cx-freeze 7.2.0.
  2. Build using the setup.py script (see below).
  3. Attempt to run the executable and encounter the error.

Expected Behavior

The executable should run without errors, as it does when using cx-freeze 7.1.1.

Actual Behavior

The executable built with cx-freeze 7.2.0 fails to run, showing the following error:

main.qml module "QtQuick.Window" is not installed

Additional Information

The setup.py file used for both cx-freeze 7.2.0 and 7.1.1 is as follows:

import sys
import os
from cx_Freeze import setup, Executable

# ADD FILES
files = ['Rx.ico', 'resources/', 'translations/']

build_exe_options = {
    "packages": ["sys", "PySide6", "os"],
    "excludes": ["tkinter", "matplotlib", "pandas", "IPython", "jedi", "prompt_toolkit", "numpy", "scipy", "pyQt6"]
}

# TARGET
target = Executable(
    script="main.py",
    icon="Elecholic.ico"
)

# SETUP CX FREEZE
setup(
    name="Ex Studio",
    version="1.0",
    description="Modern GUI",
    author="Richhard",
    options={'build_exe': {'include_files': files}},
    executables=[target]
)

Observations

Any guidance or suggestions to resolve this issue would be appreciated. Thank you!


marcelotduarte commented 1 week ago

Release 7.2.1 is out! Documentation

Please test and give me feedback, including if the exec size is lower than before.

isaacwaldron commented 4 days ago

@marcelotduarte I ran into a similar issue with QtQuick failing to load in >7.1.1, but 7.2.1 does not seem to resolve this either. To reproduce, use cx_setup.py to build a frozen version of qml_test.py as shown below. Running the produced executable results in the dialog box shown below. I was about to open a new issue for this before finding this one, please let me know if you prefer a new issue.

pip install "cx_freeze>7.1.1" "pyside6==6.7.0"
python cx_setup.py build
build\exe.win-amd64-3.12\qml_test.exe

image

cx_setup.py

import sys

from cx_Freeze import Executable, setup

import qml_test

base = "Win32GUI" if sys.platform == "win32" else None

setup(
    name="qml_test",
    version="0.1.dev0",
    description="QML Test App",
    executables=[
        Executable(qml_test.__file__, base=base, target_name="qml_test"),
    ],
)

qml_test.py

import sys
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtQuickControls2 import QQuickStyle

VIEW_DATA = b"""
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls

ApplicationWindow {
    id: main

    title: qsTr("app")
    width: 1100
    minimumWidth: 1100
    height: 800
    minimumHeight: 800
    visible: true

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 5

        TabBar {
            id: tab_bar
            TabButton {
                text: qsTr("Tab 1")
                width: implicitWidth
            }
            TabButton {
                text: qsTr("Tab 2")
                width: implicitWidth
            }
            TabButton {
                text: qsTr("Tab 3")
                width: implicitWidth
            }
        }

        StackLayout {
            currentIndex: tab_bar.currentIndex
            Rectangle {
                Layout.fillHeight: true
                Layout.fillWidth: true
                color: "red"
            }
            GridLayout {
                columns: 3
                Rectangle {
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    Layout.columnSpan: 3
                    color: "green"
                }
            }
            ColumnLayout {
                GroupBox {
                    Layout.fillWidth: true
                    RowLayout {
                        anchors.verticalCenter: parent.verticalCenter
                        anchors.horizontalCenter: parent.horizontalCenter

                        Rectangle {
                            color: "blue"
                            height: 50
                            width: 100
                        }
                    }
                }
            }
        }
    }
}
"""

def main() -> int:
    app = QGuiApplication()
    app.setOrganizationName("example")
    app.setOrganizationDomain("example.com")
    QQuickStyle.setStyle("Universal")
    engine = QQmlApplicationEngine()
    engine.loadData(VIEW_DATA)

    if not engine.rootObjects():
        return -1

    app.aboutToQuit.connect(engine.rootObjects()[0].deleteLater)
    return app.exec()

if __name__ == "__main__":
    sys.exit(main())
marcelotduarte commented 2 days ago

@isaacwaldron Can you test the PR #2577? pip install git+https://github.com/marcelotduarte/cx_Freeze.git@refs/pull/2577/head

isaacwaldron commented 11 hours ago

@marcelotduarte I checked this with two other projects that were exposing the same issue and both are working with this PR #2577. Thank you for the quick turnaround!