Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport bug fixes for 7.0.1 release #562

Merged
merged 6 commits into from
Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ matrix:
env: RUNTIME=3.6 TOOLKITS="pyqt pyqt5 pyside2 wx"
fast_finish: true

branches:
only:
- master

cache:
directories:
- "~/.cache"
Expand Down
18 changes: 18 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
Pyface Changelog
================

Release 7.0.1
=============

This is a bugfix release which fixes a number of minor issues with the 7.0.0
release.

Thanks to:

Kit Choi, Rahul Poruri, Pedro Rivotti, Corran Webster.

Change summary
--------------

Fixes

* Fix dock pane layout on Qt5. (#545)
* Fix errors from incorrect QImage memory management. (#546)

Release 7.0.0
=============

Expand Down
5 changes: 0 additions & 5 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ matrix:
- RUNTIME: '3.6'
TOOLKITS: "pyside2 pyqt5"


branches:
only:
- master

cache:
- C:\Users\appveyor\.cache -> appveyor-clean-cache.txt
- C:\Users\appveyor\AppData\Local\pip\Cache -> appveyor-clean-cache.txt
Expand Down
26 changes: 16 additions & 10 deletions pyface/ui/qt4/tasks/main_window_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import logging


from pyface.qt import QtCore, QtGui
from pyface.qt import QtCore, QtGui, is_qt4


from traits.api import Any, HasTraits
Expand Down Expand Up @@ -154,8 +154,9 @@ def set_layout(self, layout):
sublayout, q_dock_area, _toplevel_call=False
)

# Remove the fixed sizes once Qt activates the layout.
QtCore.QTimer.singleShot(0, self._reset_fixed_sizes)
if is_qt4:
# Remove the fixed sizes once Qt activates the layout.
QtCore.QTimer.singleShot(0, self._reset_fixed_sizes)

def set_layout_for_area(
self, layout, q_dock_area, _toplevel_added=False, _toplevel_call=True
Expand Down Expand Up @@ -227,9 +228,10 @@ def set_layout_for_area(
else:
raise MainWindowLayoutError("Unknown layout item %r" % layout)

# Remove the fixed sizes once Qt activates the layout.
if _toplevel_call:
QtCore.QTimer.singleShot(0, self._reset_fixed_sizes)
if is_qt4:
# Remove the fixed sizes once Qt activates the layout.
if _toplevel_call:
QtCore.QTimer.singleShot(0, self._reset_fixed_sizes)

# ------------------------------------------------------------------------
# 'MainWindowLayout' abstract interface.
Expand Down Expand Up @@ -309,10 +311,14 @@ def _prepare_toplevel_for_item(self, layout):
"Cannot retrieve dock widget for pane %r" % layout.id
)
else:
if layout.width > 0:
dock_widget.widget().setFixedWidth(layout.width)
if layout.height > 0:
dock_widget.widget().setFixedHeight(layout.height)
if is_qt4:
if layout.width > 0:
dock_widget.widget().setFixedWidth(layout.width)
if layout.height > 0:
dock_widget.widget().setFixedHeight(layout.height)
else:
sizeHint = lambda : QtCore.QSize(layout.width, layout.height)
dock_widget.widget().sizeHint = sizeHint
return dock_widget

elif isinstance(layout, LayoutContainer):
Expand Down
128 changes: 128 additions & 0 deletions pyface/ui/qt4/tasks/tests/test_main_window_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!

import unittest
from unittest import mock

from pyface.tasks.api import TaskLayout, PaneItem
from pyface.toolkit import toolkit_object
from pyface.window import Window

try:
from pyface.qt import QtGui
from pyface.ui.qt4.tasks.main_window_layout import MainWindowLayout
except ImportError:
if toolkit_object.toolkit == "qt4":
raise


GuiTestAssistant = toolkit_object("util.gui_test_assistant:GuiTestAssistant")


def create_dummy_dock_widget(parent):
""" Create a dummy QDockWidget with a dummy child widget for test.

Parameters
----------
parent : QObject

Returns
-------
dock_widget : QDockWidget
"""
dock_widget = QtGui.QDockWidget(parent)
content_widget = QtGui.QWidget(parent)
dock_widget.setWidget(content_widget)
return dock_widget


@unittest.skipIf(
toolkit_object.toolkit != "qt4",
"This test targets Qt specific MainWindowLayout. "
"Current toolkit is not Qt."
)
class TestMainWindowLayout(unittest.TestCase, GuiTestAssistant):
""" Test Qt specific MainWindowLayout.

Note that MainWindowLayout does not have a toolkit-agnostic interface
in the ``pyface.tasks`` package. Therefore this test is Qt-only.
"""

def setUp(self):
GuiTestAssistant.setUp(self)
self.window = Window(size=(500, 500))
self.window._create()

def tearDown(self):
if self.window.control is not None:
with self.delete_widget(self.window.control):
self.window.destroy()
del self.window
GuiTestAssistant.tearDown(self)

def setup_window_with_central_widget(self):
# Add a central widget to the main window.
# The main window takes ownership of the child widget.
central_widget = QtGui.QWidget(parent=self.window.control)
self.window.control.setCentralWidget(central_widget)

def test_set_pane_item_width_in_main_window_layout(self):
# Test the dock pane width is as expected.

self.setup_window_with_central_widget()

# Set the dock widget expected width to be smaller than the window
# for a meaningful test.
expected_width = self.window.size[0] // 2
window_layout = MainWindowLayout(control=self.window.control)
dock_layout = TaskLayout(
left=PaneItem(width=expected_width)
)
dock_widget = create_dummy_dock_widget(parent=self.window.control)
patch_get_dock_widget = mock.patch.object(
MainWindowLayout, "_get_dock_widget",
return_value=dock_widget,
)

# when
with self.event_loop():
with patch_get_dock_widget:
window_layout.set_layout(dock_layout)

# then
size = dock_widget.widget().size()
self.assertEqual(size.width(), expected_width)

def test_set_pane_item_height_in_main_window_layout(self):
# Test the dock pane height is as expected.

self.setup_window_with_central_widget()

# Set the dock widget expected height to be smaller than the window
# for a meaningful test.
expected_height = self.window.size[1] // 2
window_layout = MainWindowLayout(control=self.window.control)
dock_layout = TaskLayout(
bottom=PaneItem(height=expected_height)
)
dock_widget = create_dummy_dock_widget(parent=self.window.control)
patch_get_dock_widget = mock.patch.object(
MainWindowLayout, "_get_dock_widget",
return_value=dock_widget,
)

# when
with self.event_loop():
with patch_get_dock_widget:
window_layout.set_layout(dock_layout)

# then
size = dock_widget.widget().size()
self.assertEqual(size.height(), expected_height)
1 change: 1 addition & 0 deletions pyface/ui/qt4/util/image_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@ def array_to_QImage(array):
elif channels == 4:
image = QImage(data.data, width, height, bytes_per_line,
QImage.Format_ARGB32)
image._numpy_data = data
return image