Пример #1
0
    def get(self, url):
        future = Future()
        url = url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader("User-Agent", "OWImageViewer/1.0")
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply
        n_redir = 0

        def on_reply_ready(reply, future):
            nonlocal n_redir
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request itself was canceled
                future.cancel()
                return

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                print(location)
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                return

            reader = QImageReader(reply)
            image = reader.read()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #2
0
    def get(self, tile):
        future = Future()
        url = QUrl(tile.url)
        request = QNetworkRequest(url)
        # Modified by Jean 2020/05/21 to support tianditu.gov.cn
        # request.setRawHeader(b"User-Agent", b"OWMap/1.0")
        request.setRawHeader(b"User-Agent", b"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0")
        
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )
        request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True)
        request.setMaximumRedirectsAllowed(5)

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply
        future._tile = tile

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        def on_reply_ready(reply, future):
            # type: (QNetworkReply, Future) -> None

            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None

            with closing(reply):
                if not future.set_running_or_notify_cancel():
                    return

                if reply.error() != QNetworkReply.NoError:
                    # XXX Maybe convert the error into standard http and
                    # urllib exceptions.
                    future.set_exception(Exception(reply.errorString()))
                    return

                try:
                    image = Image.open(BytesIO(reply.readAll()))
                except Exception as e:
                    future.set_exception(e)
                else:
                    tile.disc_cache = reply.attribute(
                        QNetworkRequest.SourceIsFromCacheAttribute)
                    future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #3
0
    def get(self, url):
        future = Future()
        url = url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader("User-Agent", "OWImageViewer/1.0")
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply
        n_redir = 0

        def on_reply_ready(reply, future):
            nonlocal n_redir
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request itself was canceled
                future.cancel()
                return

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                return

            reader = QImageReader(reply)
            image = reader.read()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #4
0
    def setupScene(self):
        self.error()
        if self.data:
            attr = self.stringAttrs[self.smilesAttr]
            titleAttr = self.allAttrs[self.titleAttr]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            for i, inst in enumerate(self.data):
                if not numpy.isfinite(inst[attr]):  # skip missing
                    continue

                smiles = str(inst[attr])
                title = str(inst[titleAttr])

                thumbnail = GraphicsThumbnailWidget(QPixmap(), title=title)
                thumbnail.setThumbnailSize(size)
                thumbnail.setToolTip(smiles)
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if self.check_smiles(smiles):
                    pixmap = self.pixmap_from_smiles(smiles)
                    thumbnail.setPixmap(pixmap)
                    self._successcount += 1

                else:
                    pixmap = QPixmap()
                    thumbnail.setPixmap(pixmap)
                    thumbnail.setToolTip(thumbnail.toolTip() +
                                         "\nInvalid SMILES")
                    self._errcount += 1

                future = Future()
                future.set_result(pixmap)
                future._reply = None

                self.items.append(_ImageItem(i, thumbnail, smiles, future))

            if any(it.future is not None and not it.future.done()
                   for it in self.items):
                self.info.setText("Retrieving...\n")
            else:
                self._updateStatus()
Пример #5
0
    def setupScene(self):
        self.error()
        if self.data:
            attr = self.stringAttrs[self.imageAttr]
            titleAttr = self.allAttrs[self.titleAttr]
            instances = [inst for inst in self.data
                         if numpy.isfinite(inst[attr])]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            for i, inst in enumerate(instances):
                url = self.urlFromValue(inst[attr])
                title = str(inst[titleAttr])

                thumbnail = GraphicsThumbnailWidget(QPixmap(), title=title)
                thumbnail.setThumbnailSize(size)
                thumbnail.setToolTip(url.toString())
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if url.isValid() and url.isLocalFile():
                    reader = QImageReader(url.toLocalFile())
                    image = reader.read()
                    if image.isNull():
                        error = reader.errorString()
                        thumbnail.setToolTip(
                            thumbnail.toolTip() + "\n" + error)
                        self._errcount += 1
                    else:
                        pixmap = QPixmap.fromImage(image)
                        thumbnail.setPixmap(pixmap)
                        self._successcount += 1

                    future = Future()
                    future.set_result(image)
                    future._reply = None
                elif url.isValid():
                    future = self.loader.get(url)

                    @future.add_done_callback
                    def set_pixmap(future, thumb=thumbnail):
                        if future.cancelled():
                            return

                        assert future.done()

                        if future.exception():
                            # Should be some generic error image.
                            pixmap = QPixmap()
                            thumb.setToolTip(thumb.toolTip() + "\n" +
                                             str(future.exception()))
                        else:
                            pixmap = QPixmap.fromImage(future.result())

                        thumb.setPixmap(pixmap)

                        self._noteCompleted(future)
                else:
                    future = None

                self.items.append(_ImageItem(i, thumbnail, url, future))

            if any(it.future is not None and not it.future.done()
                   for it in self.items):
                self.info.setText("Retrieving...\n")
            else:
                self._updateStatus()
Пример #6
0
    def get(self, url):
        future = Future()
        url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader(b"User-Agent", b"OWImageViewer/1.0")
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        n_redir = 0

        def on_reply_ready(reply, future):
            nonlocal n_redir
            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request was cancelled
                reply.close()
                future.cancel()
                return

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                reply.close()
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                reply.close()
                return

            reader = QImageReader(reply)
            image = reader.read()
            reply.close()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #7
0
    def setupScene(self):
        self.error()
        if self.data:
            attr = self.stringAttrs[self.imageAttr]
            titleAttr = self.allAttrs[self.titleAttr]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            for i, inst in enumerate(self.data):
                if not numpy.isfinite(inst[attr]):  # skip missing
                    continue
                url = self.urlFromValue(inst[attr])
                title = str(inst[titleAttr])

                thumbnail = GraphicsThumbnailWidget(QPixmap(), title=title)
                thumbnail.setThumbnailSize(size)
                thumbnail.setToolTip(url.toString())
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if url.isValid() and url.isLocalFile():
                    reader = QImageReader(url.toLocalFile())
                    image = reader.read()
                    if image.isNull():
                        error = reader.errorString()
                        thumbnail.setToolTip(thumbnail.toolTip() + "\n" +
                                             error)
                        self._errcount += 1
                    else:
                        pixmap = QPixmap.fromImage(image)
                        thumbnail.setPixmap(pixmap)
                        self._successcount += 1

                    future = Future()
                    future.set_result(image)
                    future._reply = None
                elif url.isValid():
                    future = self.loader.get(url)

                    @future.add_done_callback
                    def set_pixmap(future, thumb=thumbnail):
                        if future.cancelled():
                            return

                        assert future.done()

                        if future.exception():
                            # Should be some generic error image.
                            pixmap = QPixmap()
                            thumb.setToolTip(thumb.toolTip() + "\n" +
                                             str(future.exception()))
                        else:
                            pixmap = QPixmap.fromImage(future.result())

                        thumb.setPixmap(pixmap)

                        self._noteCompleted(future)
                else:
                    future = None

                self.items.append(_ImageItem(i, thumbnail, url, future))

            if any(it.future is not None and not it.future.done()
                   for it in self.items):
                self.info.setText("Retrieving...\n")
            else:
                self._updateStatus()
Пример #8
0
    def get(self, url):
        future = Future()
        url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader(b"User-Agent", b"OWImageViewer/1.0")
        request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
                             QNetworkRequest.PreferCache)

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        n_redir = 0

        def on_reply_ready(reply, future):
            nonlocal n_redir
            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request was cancelled
                reply.close()
                future.cancel()
                return

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                reply.close()
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                reply.close()
                return

            reader = QImageReader(reply)
            image = reader.read()
            reply.close()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
    def get(self, url):
        future = Future()
        url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader(b"User-Agent", b"OWImageViewer/1.0")
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )

        if QT_VERSION >= 0x50600:
            request.setAttribute(
                QNetworkRequest.FollowRedirectsAttribute, True
            )
            request.setMaximumRedirectsAllowed(5)

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        n_redir = 0

        def on_reply_ready(reply, future):
            # type: (QNetworkReply, Future) -> None
            nonlocal n_redir
            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request was cancelled
                reply.close()
                future.cancel()
                return

            if _log.level <= logging.DEBUG:
                s = io.StringIO()
                print("\n", reply.url(), file=s)
                if reply.attribute(QNetworkRequest.SourceIsFromCacheAttribute):
                    print("  (served from cache)", file=s)
                for name, val in reply.rawHeaderPairs():
                    print(bytes(name).decode("latin-1"), ":",
                          bytes(val).decode("latin-1"), file=s)
                _log.debug(s.getvalue())

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                reply.close()
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                reply.close()
                return

            reader = QImageReader(reply)
            image = reader.read()
            reply.close()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #10
0
    def setup_scene(self, process_grid=True):
        self.clear_scene()
        self.error()
        if self.data:
            attr = self.stringAttrs[self.imageAttr]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            if process_grid and self.image_grid:
                self.process()
                self.columns = self.image_grid.size_x
                self.rows = self.image_grid.size_y

            self.thumbnailView.setFixedColumnCount(self.columns)
            self.thumbnailView.setFixedRowCount(self.rows)

            for i, inst in enumerate(self.image_grid.image_list):
                label_text = (str(inst[self.label_attr])
                              if self.label_attr is not None else "")
                if label_text == "?":
                    label_text = ""

                thumbnail = GraphicsThumbnailWidget(
                    QPixmap(),
                    crop=self.cell_fit == 1,
                    add_label=self.label_selected
                    and self.label_attr is not None,
                    text=label_text)
                thumbnail.setThumbnailSize(size)
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if not np.isfinite(inst[attr]) or inst[attr] == "?":
                    # skip missing
                    future, url = None, None
                else:
                    url = self.url_from_value(inst[attr])
                    thumbnail.setToolTip(url.toString())
                    self.nonempty.append(i)

                    if url.isValid() and url.isLocalFile():
                        reader = QImageReader(url.toLocalFile())
                        image = reader.read()
                        if image.isNull():
                            error = reader.errorString()
                            thumbnail.setToolTip(thumbnail.toolTip() + "\n" +
                                                 error)

                            self._errcount += 1
                        else:
                            pixmap = QPixmap.fromImage(image)
                            thumbnail.setPixmap(pixmap)
                            self._successcount += 1

                        future = Future()
                        future.set_result(image)
                        future._reply = None
                    elif url.isValid():
                        future = self.loader.get(url)

                        @future.add_done_callback
                        def set_pixmap(future, thumb=thumbnail):
                            if future.cancelled():
                                return

                            assert future.done()

                            if future.exception():
                                # Should be some generic error image.
                                pixmap = QPixmap()
                                thumb.setToolTip(thumb.toolTip() + "\n" +
                                                 str(future.exception()))
                            else:
                                pixmap = QPixmap.fromImage(future.result())

                            thumb.setPixmap(pixmap)

                            self._note_completed(future)
                    else:
                        future = None

                self.items.append(_ImageItem(i, thumbnail, url, future))

            if not any(not it.future.done() if it.future else False
                       for it in self.items):
                self._update_status()
                self.apply_subset()
                self.update_selection()
Пример #11
0
    def get(self, url):
        future = Future()
        url = QUrl(url)
        request = QNetworkRequest(url)
        request.setRawHeader(b"User-Agent", b"OWImageViewer/1.0")
        request.setAttribute(
            QNetworkRequest.CacheLoadControlAttribute,
            QNetworkRequest.PreferCache
        )

        if QT_VERSION >= 0x50600:
            request.setAttribute(
                QNetworkRequest.FollowRedirectsAttribute, True
            )
            request.setMaximumRedirectsAllowed(5)

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        n_redir = 0

        def on_reply_ready(reply, future):
            # type: (QNetworkReply, Future) -> None
            nonlocal n_redir
            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None
            if reply.error() == QNetworkReply.OperationCanceledError:
                # The network request was cancelled
                reply.close()
                future.cancel()
                return

            if _log.level <= logging.DEBUG:
                s = io.StringIO()
                print("\n", reply.url(), file=s)
                if reply.attribute(QNetworkRequest.SourceIsFromCacheAttribute):
                    print("  (served from cache)", file=s)
                for name, val in reply.rawHeaderPairs():
                    print(bytes(name).decode("latin-1"), ":",
                          bytes(val).decode("latin-1"), file=s)
                _log.debug(s.getvalue())

            if reply.error() != QNetworkReply.NoError:
                # XXX Maybe convert the error into standard
                # http and urllib exceptions.
                future.set_exception(Exception(reply.errorString()))
                reply.close()
                return

            # Handle a possible redirection
            location = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)

            if location is not None and n_redir < 1:
                n_redir += 1
                location = reply.url().resolved(location)
                # Retry the original request with a new url.
                request = QNetworkRequest(reply.request())
                request.setUrl(location)
                newreply = self._netmanager.get(request)
                future._reply = newreply
                newreply.finished.connect(
                    partial(on_reply_ready, newreply, future))
                reply.close()
                return

            reader = QImageReader(reply)
            image = reader.read()
            reply.close()

            if image.isNull():
                future.set_exception(Exception(reader.errorString()))
            else:
                future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #12
0
    def get(self, tile):
        future = Future()
        url = QUrl(tile.url)
        request = QNetworkRequest(url)
        # Modified by Jean 2020/05/21 to support tianditu.gov.cn
        # request.setRawHeader(b"User-Agent", b"OWMap/1.0")
        # request.setRawHeader(b"User-Agent", b"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0")
        request.setRawHeader(
            b'User-Agent',
            b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'
        )
        # Updated by Jean @ 2022/1/6
        request.setRawHeader(
            b'Accept',
            b'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8'
        )
        request.setRawHeader(b'Accept-Encoding', b'gzip, deflate, br')
        request.setRawHeader(b'Accept-Language', b'zh-CN,zh;q=0.9')
        request.setRawHeader(
            b'sec-ch-ua',
            b'" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"'
        )
        request.setRawHeader(b'sec-ch-ua-mobile', b'?0')
        request.setRawHeader(b'Upgrade-Insecure-Requests', b'1')

        request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
                             QNetworkRequest.PreferCache)
        request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True)
        request.setMaximumRedirectsAllowed(5)

        # Future yielding a QNetworkReply when finished.
        reply = self._netmanager.get(request)
        future._reply = reply
        future._tile = tile

        @future.add_done_callback
        def abort_on_cancel(f):
            # abort the network request on future.cancel()
            if f.cancelled() and f._reply is not None:
                f._reply.abort()

        def on_reply_ready(reply, future):
            # type: (QNetworkReply, Future) -> None

            # schedule deferred delete to ensure the reply is closed
            # otherwise we will leak file/socket descriptors
            reply.deleteLater()
            future._reply = None

            with closing(reply):
                if not future.set_running_or_notify_cancel():
                    return

                if reply.error() != QNetworkReply.NoError:
                    # XXX Maybe convert the error into standard http and
                    # urllib exceptions.
                    future.set_exception(Exception(reply.errorString()))
                    return

                try:
                    image = Image.open(BytesIO(reply.readAll()))
                except Exception as e:
                    future.set_exception(e)
                else:
                    tile.disc_cache = reply.attribute(
                        QNetworkRequest.SourceIsFromCacheAttribute)
                    future.set_result(image)

        reply.finished.connect(partial(on_reply_ready, reply, future))
        return future
Пример #13
0
    def setup_scene(self, process_grid=True):
        self.error()
        if self.data:
            attr = self.stringAttrs[self.imageAttr]
            assert self.thumbnailView.count() == 0
            size = QSizeF(self.imageSize, self.imageSize)

            if process_grid and self.image_grid:
                self.process()
                self.columns = self.image_grid.size_x
                self.rows = self.image_grid.size_y

            self.thumbnailView.setFixedColumnCount(self.columns)
            self.thumbnailView.setFixedRowCount(self.rows)

            for i, inst in enumerate(self.image_grid.image_list):
                thumbnail = GraphicsThumbnailWidget(QPixmap(), crop=self.cell_fit == 1)
                thumbnail.setThumbnailSize(size)
                thumbnail.instance = inst
                self.thumbnailView.addThumbnail(thumbnail)

                if not np.isfinite(inst[attr]) or inst[attr] == "?":  # skip missing
                    future, url = None, None
                else:
                    url = self.url_from_value(inst[attr])
                    thumbnail.setToolTip(url.toString())
                    self.nonempty.append(i)

                    if url.isValid() and url.isLocalFile():
                        reader = QImageReader(url.toLocalFile())
                        image = reader.read()
                        if image.isNull():
                            error = reader.errorString()
                            thumbnail.setToolTip(
                                thumbnail.toolTip() + "\n" + error)

                            self._errcount += 1
                        else:
                            pixmap = QPixmap.fromImage(image)
                            thumbnail.setPixmap(pixmap)
                            self._successcount += 1

                        future = Future()
                        future.set_result(image)
                        future._reply = None
                    elif url.isValid():
                        future = self.loader.get(url)

                        @future.add_done_callback
                        def set_pixmap(future, thumb=thumbnail):
                            if future.cancelled():
                                return

                            assert future.done()

                            if future.exception():
                                # Should be some generic error image.
                                pixmap = QPixmap()
                                thumb.setToolTip(thumb.toolTip() + "\n" +
                                                 str(future.exception()))
                            else:
                                pixmap = QPixmap.fromImage(future.result())

                            thumb.setPixmap(pixmap)

                            self._note_completed(future)
                    else:
                        future = None

                self.items.append(_ImageItem(i, thumbnail, url, future))

            if any(not it.future.done() if it.future else False for it in self.items):
                self.info.setText("Retrieving...\n")
            else:
                self._update_status()
                self.apply_subset()
                self.update_selection()