Repository: pandas-dev/pandas

Issue:
Qtbindings clipboard conflict
In the clipboard package, I see pandas is using pyperclip

the problem is that pyperclip uses PyQt4 when deciding to use Qt for the linux clipboard, which can create a conflict if trying to embed pandas into a PyQt5 or PySide application for example

I think the simplest solution is to use [qtpy from the Spyder](https://github.com/spyder-ide/qtpy) team, so replace:

```python
from PyQt4.QtGui import QApplication
```

with

```python
from qtpy.QtWidgets import QApplication
```

I am currently working on a PyQt5 based pandas data visualization program and this is a problem I have encountered in the past.


Discussion:
Thanks for the report. Do you have a link from Spyder team answer? Also, PR is appreciated. 

Resolving patch:
diff --git a/pandas/io/clipboard/__init__.py b/pandas/io/clipboard/__init__.py
--- a/pandas/io/clipboard/__init__.py
+++ b/pandas/io/clipboard/__init__.py
@@ -18,7 +18,8 @@
 On Linux, install xclip or xsel via package manager. For example, in Debian:
 sudo apt-get install xclip
 
-Otherwise on Linux, you will need the gtk or PyQt4 modules installed.
+Otherwise on Linux, you will need the gtk, qtpy or PyQt modules installed.
+qtpy also requires a python-qt-bindings module: PyQt4, PyQt5, PySide, PySide2
 
 gtk and PyQt4 modules are not available for Python 3,
 and this module does not work with PyGObject yet.
@@ -34,9 +35,9 @@
                          init_klipper_clipboard, init_no_clipboard)
 from .windows import init_windows_clipboard
 
-# `import PyQt4` sys.exit()s if DISPLAY is not in the environment.
+# `import qtpy` sys.exit()s if DISPLAY is not in the environment.
 # Thus, we need to detect the presence of $DISPLAY manually
-# and not load PyQt4 if it is absent.
+# and not load qtpy if it is absent.
 HAS_DISPLAY = os.getenv("DISPLAY", False)
 CHECK_CMD = "where" if platform.system() == "Windows" else "which"
 
@@ -68,9 +69,23 @@ def determine_clipboard():
             return init_gtk_clipboard()
 
         try:
-            # Check if PyQt4 is installed
-            import PyQt4  # noqa
+            # qtpy is a small abstraction layer that lets you write
+            # applications using a single api call to either PyQt or PySide
+            # https://pypi.python.org/pypi/QtPy
+            import qtpy  # noqa
         except ImportError:
+            # If qtpy isn't installed, fall back on importing PyQt5, or PyQt5
+            try:
+                import PyQt5  # noqa
+            except ImportError:
+                try:
+                    import PyQt4  # noqa
+                except ImportError:
+                    pass  # fail fast for all non-ImportError exceptions.
+                else:
+                    return init_qt_clipboard()
+            else:
+                return init_qt_clipboard()
             pass
         else:
             return init_qt_clipboard()
diff --git a/pandas/io/clipboard/clipboards.py b/pandas/io/clipboard/clipboards.py
--- a/pandas/io/clipboard/clipboards.py
+++ b/pandas/io/clipboard/clipboards.py
@@ -46,10 +46,19 @@ def paste_gtk():
 
 def init_qt_clipboard():
     # $DISPLAY should exist
-    from PyQt4.QtGui import QApplication
 
-    # use the global instance if it exists
-    app = QApplication.instance() or QApplication([])
+    # Try to import from qtpy, but if that fails try PyQt5 then PyQt4
+    try:
+        from qtpy.QtWidgets import QApplication
+    except ImportError:
+        try:
+            from PyQt5.QtWidgets import QApplication
+        except ImportError:
+            from PyQt4.QtGui import QApplication
+
+    app = QApplication.instance()
+    if app is None:
+        app = QApplication([])
 
     def copy_qt(text):
         cb = app.clipboard()


Test patch:
diff --git a/ci/requirements-3.6_BUILD_TEST.sh b/ci/requirements-3.6_BUILD_TEST.sh
--- a/ci/requirements-3.6_BUILD_TEST.sh
+++ b/ci/requirements-3.6_BUILD_TEST.sh
@@ -4,4 +4,4 @@ source activate pandas
 
 echo "install 36 BUILD_TEST"
 
-conda install -n pandas -c conda-forge pyarrow dask
+conda install -n pandas -c conda-forge pyarrow dask pyqt qtpy