前提・実現したいこと
このプログラムは、ウィンドウの大きさを変えてもウィジェットや画像の位置が分からないのですが、
ウィンドウの大きさに伴って、ウィジェットの位置と画像の大きさが変わるようにしたいです。
該当のソースコード
import sys import cv2 from PyQt5 import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * class MainWindow(QMainWindow): # メインウィンドウの構成 def __init__(self): # メインウィンドウの初期値を設定 super().__init__() self.title = 'Movie Viewer for PDET' self.left = 10 self.top = 40 self.width = 720 self.height = 540 self.count = 0 self.cntFlg = False self.image = None self.moviePlayFlg = False self.imgWidth = 100 self.imgHeight = 50 self.frameRate = 30 self.frameNum = 0 self.frameMaxNum = 0 self.time = 0 self.minute = 0 self.second = 0 self.millisecond = 0 self.now_time = 0 self.setWindowTitle(self.title) # メインウィンドウのタイトルを設定する self.setGeometry(self.left, self.top, self.width, self.height) # メインウィンドウの初期位置 hbox = QHBoxLayout(self) mainMenu = self.menuBar() # メインウィンドウのメニューを設定する fileMenu = mainMenu.addMenu('File') editMenu = mainMenu.addMenu('Edit') optionMenu = mainMenu.addMenu('Option') helpMenu = mainMenu.addMenu('Help') fileOpenButton = QAction(self.style().standardIcon(getattr(QStyle, 'SP_FileDialogStart')), 'File Open', self) # ファイルを開くメニューを設定する fileOpenButton.setShortcut('Ctrl+O') fileOpenButton.triggered.connect(self.openFileDialog) fileMenu.addAction(fileOpenButton) exitButton = QAction(self.style().standardIcon(getattr(QStyle, 'SP_DialogCloseButton')), 'Exit', self) # アプリの終了メニューを設定する exitButton.setShortcut('Ctrl+Q') exitButton.setStatusTip('Exit application') exitButton.triggered.connect(self.close) fileMenu.addAction(exitButton) fps240Button = QAction('240fps', self) fps240Button.triggered.connect(self.video240fps) editMenu.addAction(fps240Button) fps120Button = QAction('120fps', self) fps120Button.triggered.connect(self.video120fps) editMenu.addAction(fps120Button) fps60Button = QAction('60fps', self) fps60Button.triggered.connect(self.video60fps) editMenu.addAction(fps60Button) fps30Button = QAction('30fps', self) fps30Button.triggered.connect(self.video30fps) editMenu.addAction(fps30Button) self.setLayout(hbox) self.lblfps = QLabel(self) # ラベルオブジェクト作成 self.lblfps.move(550, 20) self.bb = QPushButton(self.style().standardIcon(getattr(QStyle, 'SP_MediaSeekBackward')), 'Backward', self) # 1フレーム戻りのボタンを設定する self.bb.move(120, self.height-50) self.lbltime = QLabel(self) # ラベルオブジェクト作成 self.lbltime.move(230, self.height-50) self.fb = QPushButton(self.style().standardIcon(getattr(QStyle, 'SP_MediaSeekForward')), 'Forward', self) # 1フレーム送りのボタンを設定する self.fb.move(320, self.height-50) self.cnt = QPushButton('Count', self) # カウントを始める self.cnt.move(420, self.height-50) self.lblcnt = QLabel(self) # ラベルオブジェクト作成 self.lblcnt.move(550, self.height-50) self.sld = QSlider(Qt.Horizontal, self) # 水平方向のスライダー作成 self.sld.setFocusPolicy(Qt.NoFocus) # スライダーがフォーカスされないようにする self.sld.setGeometry(100, self.height-80, self.width - 210, 10) self.initUI() def initUI(self): # 初期化処理をまとめておく self.bb.clicked.connect(self.movieSeekBackward) self.fb.clicked.connect(self.movieSeekForward) self.cnt.clicked.connect(self.Count) self.sld.sliderMoved[int].connect(self.changeValue) # スライダーを動かすとchangeValue関数が呼び出される def openFileDialog(self): self.moviePlayFlg = True options = QFileDialog.Options() inputFileName, _ = QFileDialog.getOpenFileName(self, 'Open File', '', 'Movie files(*.mp4 *.MOV *.avi)', options=options) self.statusBar().showMessage(inputFileName)# デバッグ用にステータスバーにファイル名を表示する self.video = cv2.VideoCapture(inputFileName) # OpenCVで動画を読み込む self.frameMaxNum = int(self.video.get(cv2.CAP_PROP_FRAME_COUNT)) # フレーム数を取得 self.frameRate = round(self.video.get(cv2.CAP_PROP_FPS))# フレームレートを取得 self.setTime() def video240fps(self): self.frameRate = 240 self.setLabel() self.update() def video120fps(self): self.frameRate = 120 self.setLabel() self.update() def video60fps(self): self.frameRate = 60 self.setLabel() self.update() def video30fps(self): self.frameRate = 30 self.setLabel() self.update() def movieSeekBackward(self): if self.frameNum > 0: if self.moviePlayFlg == False: return if (self.cntFlg == True) & (self.count > 0): self.count -= 1 self.frameNum -= 1 self.sld.setValue(int((100 / self.frameMaxNum) * self.frameNum)) self.setTime() def movieSeekForward(self): if self.frameNum < self.frameMaxNum - 1: if self.moviePlayFlg == False: return if self.cntFlg == True: self.count += 1 self.frameNum += 1 self.sld.setValue(int((100 / self.frameMaxNum) * self.frameNum)) self.setTime() def changeValue(self, value): if self.moviePlayFlg == False: return self.frameNum = int((self.frameMaxNum / 100) * value) self.setTime() def Count(self): if self.cntFlg == False: self.cntFlg = True self.count = 0 self.cnt.setText("CountON") self.update() elif self.cntFlg == True: self.cntFlg = False self.cnt.setText("CountOFF") self.update() def setTime(self): self.time = self.frameNum / self.frameRate # フレームレートを時間に変換 self.minute = int(self.time / 60) self.second = int(int(self.time) - self.minute * 60) self.millisecond = int((self.time - int(self.time)) * 1000) self.now_time = str("{:0>2}".format(self.minute)) + "分" + str("{:0>2}".format(self.second)) + "." + str("{:0>3}".format(self.millisecond) + "秒") self.setLabel() self.updateImage() def setLabel(self): self.lbltime.setText(self.now_time) # ラベルに入力されたテキストを挿入 self.lblcnt.setText(str(self.count)) self.lblfps.setText(str(self.frameRate) + "fps") def updateImage(self): if self.moviePlayFlg == False: return self.video.set(cv2.CAP_PROP_POS_FRAMES, self.frameNum) # OpenCVで動画の再生フレーム位置を設定する ret, frame = self.video.read() self.image = self.openCV2Qimage(frame) # 再生フレームをOpenCV形式からPyQtのQImageに変換する self.update() def openCV2Qimage(self, cvImage): height, width, channel = cvImage.shape bytesPerLine = channel * width cvImageRGB = cv2.cvtColor(cvImage, cv2.COLOR_BGR2RGB) image = QImage(cvImageRGB, width, height, bytesPerLine, QImage.Format_RGB888) return image def paintEvent(self, event): painter = QPainter() painter.begin(self) painter.setPen(QColor('#FFFFFF')) painter.setBrush(Qt.white) painter.drawRect(event.rect()) if self.image == None: return painter.drawImage(self.imgWidth, self.imgHeight, self.image) painter.end() if __name__ == '__main__': # アプリの実行 app = QApplication(sys.argv) ex = MainWindow() ex.show() # メインウィンドウの表示 sys.exit(app.exec_())
コード、読みづらいです。
修正時の "<コード>" または "<code>" を押して、その中にコードを書いてください。
インデントが無視されるため、回答者的に読みづらいです。
ありがとうございます。
修正しました。
レイアウト系オブジェクトを使ってボタンなんかを配置してはいかがでしょうか。
(使って…います?)
使ってないです。
レイアウト系オブジェクトは初めて聞きました。
名称はよくわかりませんが、なんちゃらLayOut ってなっているやつです。
http://vivi.dyndns.org/vivi/docs/Qt/layout.html だと QVBoxLayout とかですね。
どうしても従来通りやるなら 「ウィンドウのサイズが変更された」系のイベントでサイズ変更をする必要があります。
あなたの回答
tips
プレビュー