代码之家  ›  专栏  ›  技术社区  ›  ecjb

pyside2的相同代码在MacOS 11.2.3上运行,但在Ubuntu 20.4上抛出错误

  •  0
  • ecjb  · 技术社区  · 5 年前

    我使用PySide2、numpy和matplotlib编写GUI,在MacOS 11.2.3上运行时没有任何问题。然而,我在Ubuntu 20.4上运行代码时出错,代码正常

    我使用PySide2和matplotlib制作了一个GUI。目标是点击图像,并将点击的坐标存储在csv中。在Ubuntu上启动应用程序并点击“按钮”按钮后,我收到一条错误消息(在代码后面提供)。在Linux下,代码似乎一直运行到第91行(虽然图像上没有点击,因此,存储它们的数据帧显然是空的),而在MacOS上,解释器在第76行停止,等待用户的点击(在MacOS上,图片已经启动,终端上没有任何内容)

    以下是代码:

    import numpy as np 
    import pandas as pd
    import os
    import sys 
    import matplotlib.pyplot as plt
    
    
    from PySide2 import QtGui
    from PySide2 import QtCore
    from PySide2.QtWidgets import QWidget, QApplication, QPushButton, QFileDialog
    os.environ['QT_MAC_WANTS_LAYER'] = '1'
    
    
    
    coords_Event = [] 
    
    size_win_x = 10
    size_win_y = 7
    dpi_val = 100
    
    
    class GUI(QWidget):
        def __init__(self):
            super(GUI, self).__init__()
    
            self.initUI()
    
        def initUI(self):
            height_btn = 40 
            width_btn = 350
            
            button_position_x = 0
            button_position_y = 20 
            
            button_position_x = button_position_x + 50
            btn2 = QPushButton('Button', self)     
            btn2.clicked.connect(self.Event)
            btn2.resize(width_btn, height_btn + 20)
            btn2.move(button_position_y, button_position_x)       
    
            self.show()
    
    
        def Event(self):
            dir_path = os.getcwd()
    
            figure = plt.figure(figsize = (size_win_x,size_win_y), dpi=dpi_val) 
    
            global coords_Event
            coords_Event = []
    
            def onclick(event):
                    ix, iy = event.xdata, event.ydata
                    print('x = %d, y = %d'%(
                        ix, iy))
                    global coords_Event
                    coords_Event.append((ix, iy))
                    return coords_Event        
            cid = figure.canvas.mpl_connect('button_press_event', onclick)
    
            pixel_array = np.array([[1,2,3], [100,5,6]])
            figure2 = plt.imshow(pixel_array)
            plt.savefig(dir_path + '/raw.png')
            plt.title("the title")
            plt.show()
            
            print("ok1")
    
            df = pd.DataFrame(coords_Event,
                    columns = ['X', 'Y']) 
            string_csv = dir_path + "/coords_Event.csv"
    
            print("ok2")
            print(string_csv)
            df.to_csv(string_csv, 
            header=True)
            df2 = pd.read_csv(string_csv)  
            print("df2: ", df2)
            print(df2.iloc[0]["X"])
            print(df2.iloc[1]["X"])
            
            print("ok3")
            ic(coords_Event)
    
            clicked_data = (coords_Event[1][0] - coords_Event[0][0]) 
            df3 = pd.DataFrame ({"clicked_data": [clicked_data]})
            string_csv = dir_path + "/clicked_data.csv"
            print(string_csv)
            df3.to_csv(string_csv, 
            header=True)
            print("ok5")
    
    def main():
    
        app = QApplication(sys.argv)
        ex = GUI()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()
    

    以下是Ubuntu上的错误消息

    QCoreApplication::exec: The event loop is already running
    ok1
    []
    ok2
    /home/user/Documents/myApp/coords_Event.csv
    df2:  Empty DataFrame
    Columns: [Unnamed: 0, X, Y]
    Index: []
    Traceback (most recent call last):
      File "debug_05.py", line 92, in Event
        print(df2.iloc[0]["X"])
      File "/home/user/Documents/myApp/env/lib/python3.8/site-packages/pandas/core/indexing.py", line 895, in __getitem__
        return self._getitem_axis(maybe_callable, axis=axis)
      File "/home/user/Documents/myApp/env/lib/python3.8/site-packages/pandas/core/indexing.py", line 1501, in _getitem_axis
        self._validate_integer(key, axis)
      File "/home/user/Documents/myApp/env/lib/python3.8/site-packages/pandas/core/indexing.py", line 1444, in _validate_integer
        raise IndexError("single positional indexer is out-of-bounds")
    IndexError: single positional indexer is out-of-bounds
    
    

    我检查了Ubuntu和MacOS上的环境包,它们完全一样

    下面是一段代码,它可能更严格,在linux下输出单击的坐标,但在MacOS下不输出:

    import numpy as np 
    import pandas as pd
    import os
    import sys 
    import matplotlib.pyplot as plt
    
    
    from PySide2 import QtGui
    from PySide2 import QtCore
    from PySide2.QtWidgets import QWidget, QApplication, QPushButton, QFileDialog
    os.environ['QT_MAC_WANTS_LAYER'] = '1'
    
    coords_Event = [] 
    
    size_win_x = 2
    size_win_y = 2
    dpi_val = 100
    
    class GUI(QWidget):
        def __init__(self):
            super(GUI, self).__init__()
    
            self.initUI()
    
        def initUI(self):
            height_btn = 40 
            width_btn = 350
            
            button_position_x = 0
            button_position_y = 20 
            
            button_position_x = button_position_x + 50
            btn2 = QPushButton('Button', self)     
            btn2.clicked.connect(self.Event)
            btn2.resize(width_btn, height_btn + 20)
            btn2.move(button_position_y, button_position_x)       
    
            self.show()
    
        def Event(self):
            dir_path = os.getcwd()
    
            def onclick(event):
                global ix, iy
                ix, iy = event.xdata, event.ydata
                print('x = %d, y = %d'%(
                    ix, iy))
                global coords_Event
                coords_Event.append((ix, iy))
                return coords_Event        
    
            fig = plt.figure(figsize = (size_win_x,size_win_y), dpi=dpi_val) 
            pixel_array = np.array([[1,2,3,4,5,6], [1,2,3,4,5,6], [1,2,3,4,5,6]])
            fig2 = plt.imshow(pixel_array)
            
            cid = fig.canvas.mpl_connect('button_press_event', onclick)
    
            plt.show()
            print(coords_Event)
    
    def main():
    
        app = QApplication(sys.argv)
        ex = GUI()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   justengel    5 年前

    我在Windows上运行,你的代码也有同样的问题。

    我注意到的第一件事是,您没有指定后端。在我的系统上,点击按钮只会显示一个没有GUI的图像。在这种情况下,没有可连接的单击事件,也没有可关闭的GUI窗口。

    我假设在MacOS上会出现一个绘图图,让你在图上点击几次。一旦你关闭图表 print("ok1") 他跑了。如果是这样的话 plt.show() 正在阻塞并等待窗口关闭。这确实是一个matplotlib问题。我试着跑步 plt.show(block=True) 这对PySide2不起作用。可能存在PySide2兼容性问题、配置文件或系统设置导致不同的行为。

    下面的代码会检查figure.canvas是否可见,并阻止它直到关闭。

    import numpy as np
    import pandas as pd
    import os
    import sys
    
    from PySide2 import QtGui
    from PySide2 import QtCore
    from PySide2.QtWidgets import QWidget, QApplication, QPushButton, QFileDialog
    os.environ['QT_MAC_WANTS_LAYER'] = '1'
    
    import matplotlib
    try:
        matplotlib.rcParams['backend.qt5'] = 'PySide2'
    except (KeyError, Exception):
        pass
    matplotlib.use('Qt5Agg')
    import matplotlib.pyplot as plt
    
    
    coords_Event = []
    
    size_win_x = 10
    size_win_y = 7
    dpi_val = 100
    
    
    dir_path = os.getcwd()
    
    
    class GUI(QWidget):
        def __init__(self):
            super(GUI, self).__init__()
    
            self.initUI()
    
        def initUI(self):
            self.coords_Event = []
            height_btn = 40
            width_btn = 350
    
            button_position_x = 0
            button_position_y = 20
    
            button_position_x = button_position_x + 50
            btn2 = QPushButton('Button', self)
            btn2.clicked.connect(self.Event)
            btn2.resize(width_btn, height_btn + 20)
            btn2.move(button_position_y, button_position_x)
    
            self.show()
    
        def save_coord(self, event):
            ix, iy = event.xdata, event.ydata
            print('x = %d, y = %d' % (ix, iy))
            self.coords_Event.append((ix, iy))
            return coords_Event
    
        def Event(self):
            figure = plt.figure(figsize=(size_win_x, size_win_y), dpi=dpi_val)
    
            self.coords_Event = []
            cid = figure.canvas.mpl_connect('button_press_event', self.save_coord)
    
            pixel_array = np.array([[1, 2, 3], [100, 5, 6]])
            figure2 = plt.imshow(pixel_array)
            plt.savefig(dir_path + '/raw.png')
            plt.title("the title")
    
            # Block here until figure is closed.
            plt.show()
            while figure.canvas.isVisible():
                QApplication.processEvents()
    
            self.finish_coords()
    
        def finish_coords(self):
            print("ok1")
    
            df = pd.DataFrame(self.coords_Event, columns = ['X', 'Y'])
            string_csv = dir_path + "/coords_Event.csv"
    
            print("ok2")
            print(string_csv)
            df.to_csv(string_csv, header=True)
            df2 = pd.read_csv(string_csv)
            print("df2: ", df2)
            print(df2.iloc[0]["X"])
            print(df2.iloc[1]["X"])
    
            print("ok3")
            # ic(coords_Event)
    
            clicked_data = (self.coords_Event[1][0] - self.coords_Event[0][0])
            df3 = pd.DataFrame({"clicked_data": [clicked_data]})
            string_csv = dir_path + "/clicked_data.csv"
            print(string_csv)
            df3.to_csv(string_csv, header=True)
            print("ok5")
    
    
    def main():
        app = QApplication(sys.argv)
        ex = GUI()
        sys.exit(app.exec_())
    
    
    if __name__ == '__main__':
        main()