2017-10-19 47 views
1

私は2つのタブを持つGUI(手作業でコード化されている)を持っているプロジェクトに取り組んでいます。各タブには、それぞれのタブに異なるものをプロットするためのキャンバスがあります。 しかし、これらのタブにいくつかのウィジェットを追加しました。レイアウトに追加すると、レイアウトのボタンの同じ位置にキャンバスを追加すると、もうこのボタンをクリックできます。 私はPyQt上でウィジェットのレベルを上げることができるので、キャンバスで同じことをする方法はありますか?QWidget raise matplotlib canvas

ご協力いただきありがとうございます。この例では、「終了」は右半分だけで有効です。

import sys 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import * 

import matplotlib 
matplotlib.use('Qt5Agg') 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 
import matplotlib.pyplot as plt 
from mpl_toolkits.axes_grid1 import make_axes_locatable 

class FenetrePrincipale(QWidget): 
    def __init__(self, parent=None): 
     super(FenetrePrincipale, self).__init__(parent) 
     self.setupUi(self) 

    # Fonction de configuration de la classe 
    def setupUi(self, Form): 
     self.Form = Form 

     Form.setMinimumSize(1220, 850) 

     self.creation_GUI() 
     self.creation_figure() 
     self.creation_layout() 

     self.tabWidget.setCurrentIndex(0) 
     self.Bouton_quitter.clicked.connect(self.close) 

    def resizeEvent(self, QResizeEvent): 
     self.tabWidget.setMinimumSize(QSize(self.width() - 20, self.height() - 60)) 

    def creation_GUI(self): 
     self.tabWidget = QTabWidget() 
     self.tab1 = QWidget() 

     self.Widget_choixPalette_Label = QLabel(self.tab1) 
     self.Widget_choixPalette_Label.setText("Text1") 
     self.Widget_choixPalette_ComboBox = QComboBox(self.tab1) 
     self.Widget_choixPalette_ComboBox.addItem("Try1") 
     self.Widget_choixPalette_ComboBox.addItem("Try2") 

     self.Bouton_quitter = QPushButton(self.tab1) 
     self.Bouton_quitter.setText("Quit") 

    def creation_layout(self): 
     LayoutForm = QGridLayout(self.Form) 
     LayoutG1 = QGridLayout() 
     LayoutTab1 = QGridLayout(self.tab1) 
     WidgetTemp = QWidget() 
     LayoutWidgetTemp = QGridLayout() 

     LayoutG1.addWidget(self.Bouton_quitter, 21, 29, 1, 2, Qt.AlignRight | Qt.AlignBottom) 
     LayoutG1.addWidget(self.canvas, 2, 10, 20, 20) 

     LayoutWidgetTemp.addWidget(self.Widget_choixPalette_Label, 0, 0, 1, 4) 
     LayoutWidgetTemp.addWidget(self.Widget_choixPalette_ComboBox, 1, 0, 1, 4) 
     WidgetTemp.setLayout(LayoutWidgetTemp) 
     LayoutG1.addWidget(WidgetTemp, 1, 18, 2, 4) 

     LayoutTab1.addLayout(LayoutG1, 0, 0, 1, 1) 

     self.tabWidget.addTab(self.tab1, " Tab1 ") 

     LayoutForm.addWidget(self.tabWidget, 1, 0, 1, 1) 

    def creation_figure(self): 
     # Create figure (transparent background) 
     self.figure = plt.figure() 
     self.figure.patch.set_facecolor('None') 
     self.canvas = FigureCanvas(self.figure) 
     self.canvas.setStyleSheet("background-color:transparent;") 

     # Adding one subplot for image 
     self.axe0 = self.figure.add_subplot(111) 
     self.axe0.get_xaxis().set_visible(False) 
     self.axe0.get_yaxis().set_visible(False) 
     plt.tight_layout() 

     # Data for init image 
     self.imageInit = [[255] * 320 for i in range(240)] 
     self.imageInit[0][0] = 0 

     # Init image and add colorbar 
     self.image = self.axe0.imshow(self.imageInit, interpolation='none') 
     divider = make_axes_locatable(self.axe0) 
     cax = divider.new_vertical(size="5%", pad=0.05, pack_start=True) 
     self.colorbar = self.figure.add_axes(cax) 
     self.figure.colorbar(self.image, cax=cax, orientation='horizontal') 

     self.canvas.draw() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    # QApplication.setStyle(QStyleFactory.create("plastique")) 
    form = FenetrePrincipale() 
    form.show() 
    sys.exit(app.exec_()) 
  • オペレーティングシステム:Windows 7 Proの
  • matplotlibのバージョン:4.0.4
  • matplotlibのバックエンド:Qt5Agg
  • Pythonのバージョン:3.6
  • その他のライブラリ:PyQt5

編集25/10/17:新しいコード例:

+1

なぜ同じ位置に2つのウィジェットを追加しようとしていますか?それは決してうまくいかない。あなたは何を達成しようとしていますか? – ekhumoro

+0

図形はキャンバスのすべての領域を占めるわけではないので、図形がないところでボタンを追加する領域を最適化したいと思います。 –

+0

これを処理する正しい方法は、キャンバスの上部にある空の領域を削除することです。たぶん、 'plt.tight_layout()'を試してみてください。 – ekhumoro

答えて

2

上のボタンは、すべての問題を修正し、あなたのサンプルスクリプトのバージョンです。ほとんどの問題は、非常に混乱したレイアウトの使用によって引き起こされます。私は完全に creation_layoutメソッドを書き直す必要があったので、どこに問題があるか分かりました。キャンバスの背景色を一時的に復元して、ウィジェットが互いにどのようにレイアウトされているかを見やすくしました。私はあなたの実際のコードに私の変更の一部を組み込むことは容易ではないことに気付きます。しかし、うまくいけば、あなたのレイアウト構造を簡素化する方法についていくつかのアイデアをお寄せください。

最も重要な修正はcreation_figureメソッドでsubplots_adjustを使用することです。キャンバスの上部にある空のスペースがすべて削除されるため、他のウィジェットをその上に配置する必要はもうありません。

import sys 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 
from PyQt5.QtCore import * 

import matplotlib 
matplotlib.use('Qt5Agg') 
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 
import matplotlib.pyplot as plt 
from mpl_toolkits.axes_grid1 import make_axes_locatable 

class FenetrePrincipale(QWidget): 
    def __init__(self, parent=None): 
     super(FenetrePrincipale, self).__init__(parent) 
     self.setupUi(self) 

    # Fonction de configuration de la classe 
    def setupUi(self, Form): 
     self.Form = Form 

     Form.setMinimumSize(1220, 850) 

     self.creation_GUI() 
     self.creation_figure() 
     self.creation_layout() 

     self.tabWidget.setCurrentIndex(0) 
     self.Bouton_quitter.clicked.connect(self.close) 

    def resizeEvent(self, QResizeEvent): 
     self.tabWidget.setMinimumSize(QSize(self.width() - 20, self.height() - 60)) 

    def creation_GUI(self): 
     self.tabWidget = QTabWidget() 
     self.tab1 = QWidget() 
     self.tabWidget.addTab(self.tab1, " Tab1 ") 

     self.Widget_choixPalette_Label = QLabel(self.tab1) 
     self.Widget_choixPalette_Label.setText("Text1") 
     self.Widget_choixPalette_ComboBox = QComboBox(self.tab1) 
     self.Widget_choixPalette_ComboBox.addItem("Try1") 
     self.Widget_choixPalette_ComboBox.addItem("Try2") 

     self.Bouton_quitter = QPushButton(self.tab1) 
     self.Bouton_quitter.setText("Quit") 

    def creation_layout(self): 
     LayoutForm = QGridLayout(self) 
     LayoutForm.addWidget(self.tabWidget, 0, 0, 1, 1) 

     LayoutTab1 = QGridLayout(self.tab1) 

     LayoutTab1.addWidget(self.Widget_choixPalette_Label, 0, 1, 1, 1) 
     LayoutTab1.addWidget(self.Widget_choixPalette_ComboBox, 1, 1, 1, 1) 
     self.Widget_choixPalette_ComboBox.setMinimumWidth(200) 

     LayoutTab1.addWidget(self.canvas, 2, 0, 1, 3) 
     LayoutTab1.addWidget(self.Bouton_quitter, 2, 3, 1, 1, Qt.AlignRight | Qt.AlignBottom) 

     LayoutTab1.setRowStretch(2, 1) 
     LayoutTab1.setColumnStretch(0, 1) 
     LayoutTab1.setColumnStretch(2, 1) 

    def creation_figure(self): 
     # Create figure (transparent background) 
     self.figure = plt.figure() 
     # self.figure.patch.set_facecolor('None') 
     self.canvas = FigureCanvas(self.figure) 
     self.canvas.setStyleSheet("background-color:transparent;") 

     # Adding one subplot for image 
     self.axe0 = self.figure.add_subplot(111) 
     self.axe0.get_xaxis().set_visible(False) 
     self.axe0.get_yaxis().set_visible(False) 
     # plt.tight_layout() 

     # Data for init image 
     self.imageInit = [[255] * 320 for i in range(240)] 
     self.imageInit[0][0] = 0 

     # Init image and add colorbar 
     self.image = self.axe0.imshow(self.imageInit, interpolation='none') 
     divider = make_axes_locatable(self.axe0) 
     cax = divider.new_vertical(size="5%", pad=0.05, pack_start=True) 
     self.colorbar = self.figure.add_axes(cax) 
     self.figure.colorbar(self.image, cax=cax, orientation='horizontal') 

     plt.subplots_adjust(left=0, bottom=0.05, right=1, top=1, wspace=0, hspace=0) 

     self.canvas.draw() 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    # QApplication.setStyle(QStyleFactory.create("plastique")) 
    form = FenetrePrincipale() 
    form.show() 
    sys.exit(app.exec_()) 
+0

あなたの答えに感謝します!私の 'creation_layout'メソッドはかなり面倒ですが、ここには約30のウィジェットを持つ私の実際のGUIの小さな例があります。次回はQtDesignerを使用します。なぜなら、誰かがキャンバスのように外部ウィジェット用のウィジェットを宣伝する方法を教えてくれるからです。 私はそれが何であるかわからないので、私はまた 'ストレッチ'を見ていきます^^ –

+0

ありがとう! 'subplots_adjust'と' addColumnStretch'の間にはわかりませんでした。手でレイアウトを作成するのはとても面倒です! @ mathieuGauquelin。 –

+0

はい、私はウィジェットプロモーションでQt Designerを使用することを提案するつもりでしたが、あなたの既存のコードを変換する作業がたくさんあると思います。長期的には、あなたの人生はずっと楽になります。 – ekhumoro

1

レイアウトに物事を追加する順序を逆にします。最初のキャンバスを追加し、その後、トップ

以下
LayoutForm.addWidget(canvas,1,0,1,6) 
    LayoutForm.addWidget(button,1,0,1,2) 
+0

実際のコードでは機能しません.5つのウィジェットで同じことを行います: ' LayoutG2.addウィジェット(canvas2,1,10,21,20) ' ' LayoutG2。addWidget(Widget_choixPalette_2_Label、0、11、1、4) '' LayoutG2.addWidget(Widget_choixPalette_2_ComboBox、1、11、1、4) '' LayoutG2.addWidget(Widget_imageSelectionnee_Label、0、15、1、3) '' LayoutG2 'LayoutG2.addWidget(slide、1、18、1、5)' しかし、私はスライドだけではなく、QEditまたはQPushButtonと対話できます。たぶん私は別の何かが恋しいですか? 情報のための私のGUI(私はタブがあるため)に複数のレイアウトがあります。 –

+0

プロットしていない場合は、残りのオブジェクトと対話できますか?はいの場合、それらをレイアウトに追加し、レイアウトをキャンバスの上に配置します – Andrei

+0

2つの異なるレイアウトでウィジェットを追加して戻ってきます。 –