소스 검색

Basic PyQt5 features

simon 1 년 전
부모
커밋
f666401c3b

+ 8 - 0
basic/creating_a_window_1.py

@@ -0,0 +1,8 @@
+import sys
+
+from PyQt5.QtWidgets import QApplication, QWidget
+
+app = QApplication(sys.argv)
+window = QWidget()
+window.show()
+sys.exit(app.exec_())

+ 10 - 0
basic/creating_a_window_2.py

@@ -0,0 +1,10 @@
+import sys
+
+from PyQt5.QtWidgets import QApplication, QPushButton
+
+app = QApplication(sys.argv)
+
+window = QPushButton("Push me")
+window.show()
+
+sys.exit(app.exec_())

+ 11 - 0
basic/creating_a_window_3.py

@@ -0,0 +1,11 @@
+import sys
+
+from PyQt5.QtWidgets import QApplication, QMainWindow
+
+app = QApplication(sys.argv)
+
+window = QMainWindow()
+window.show()
+
+# Start the event loop
+sys.exit(app.exec_())

+ 23 - 0
basic/creating_a_window_4.py

@@ -0,0 +1,23 @@
+import sys
+
+from PyQt5.QtCore import QSize
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("My App")
+        button = QPushButton("Press Me!")
+
+        self.setFixedSize(QSize(400, 300))
+        # Set the central widget of the window
+        self.setCentralWidget(button)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 25 - 0
basic/signals_and_slots_1.py

@@ -0,0 +1,25 @@
+import sys
+
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+def the_button_was_clicked():
+    print("Button was clicked")
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("My App")
+        button = QPushButton("Press Me!")
+        button.clicked.connect(the_button_was_clicked)
+        # Set the central widget of the window
+        self.setCentralWidget(button)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 32 - 0
basic/signals_and_slots_1b.py

@@ -0,0 +1,32 @@
+import sys
+
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+def the_button_was_clicked():
+    print("Button was clicked")
+
+
+def the_button_was_toggled(is_checked):
+    print("Checked?", is_checked)
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("My App")
+        button = QPushButton("Press Me!")
+        button.setCheckable(True)
+        button.clicked.connect(the_button_was_clicked)
+        button.clicked.connect(the_button_was_toggled)
+
+        # Set the central widget of the window
+        self.setCentralWidget(button)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 33 - 0
basic/signals_and_slots_1c.py

@@ -0,0 +1,33 @@
+import sys
+
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+
+        self.button_is_checked = True
+
+        self.setWindowTitle("My App")
+
+        button = QPushButton("Press Me!")
+        button.setCheckable(True)
+        button.clicked.connect(self.the_button_was_toggled)
+        button.setChecked(self.button_is_checked)
+
+        # Set the central widget of the window
+        self.setCentralWidget(button)
+
+    def the_button_was_toggled(self, is_checked):
+        self.button_is_checked = is_checked
+
+        print(self.button_is_checked)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 33 - 0
basic/signals_and_slots_1d.py

@@ -0,0 +1,33 @@
+import sys
+
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+
+        self.button_is_checked = False
+
+        self.setWindowTitle("My App")
+
+        self.button = QPushButton("Press Me!")
+        self.button.setCheckable(True)
+        self.button.clicked.connect(self.the_button_was_released)
+        self.button.setChecked(self.button_is_checked)
+
+        # Set the central widget of the window
+        self.setCentralWidget(self.button)
+
+    def the_button_was_released(self):
+        self.button_is_checked = self.button.isChecked()
+
+        print(self.button_is_checked)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 25 - 0
basic/signals_and_slots_2.py

@@ -0,0 +1,25 @@
+import sys
+
+from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication
+
+
+def the_button_was_clicked():
+    print("Button was clicked")
+
+
+class MainWindow(QMainWindow):
+    def __init__(self):
+        super().__init__()
+        self.setWindowTitle("My App")
+        button = QPushButton("Press Me!")
+        button.clicked.connect(the_button_was_clicked)
+        # Set the central widget of the window
+        self.setCentralWidget(button)
+
+
+app = QApplication(sys.argv)
+
+window = MainWindow()
+window.show()
+
+app.exec_()

+ 2 - 2
load_uifile.py

@@ -1,6 +1,6 @@
 import sys
 
-from PyQt5 import QtWidgets, uic
+from PyQt5 import QtWidgets
 from PyQt5.QtWidgets import QMainWindow
 
 from MainWindow import Ui_MainWindow
@@ -20,7 +20,7 @@ if __name__ == '__main__':
     app = QtWidgets.QApplication(sys.argv)
 
     # window = uic.loadUi("mainwindow.ui")
-    # mainwindow_setup(window)
+    # main window_setup(window)
     window = MainWindow()
     window.show()
     app.exec()

+ 82 - 0
power_bar.py

@@ -0,0 +1,82 @@
+from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5.QtCore import Qt
+
+
+class _Bar(QtWidgets.QWidget):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.setSizePolicy(
+            QtWidgets.QSizePolicy.MinimumExpanding,
+            QtWidgets.QSizePolicy.MinimumExpanding
+        )
+
+    def sizeHint(self):
+        return QtCore.QSize(40, 120)
+
+    def paintEvent(self, e):
+        painter = QtGui.QPainter(self)
+        brush = QtGui.QBrush()
+        brush.setColor(QtGui.QColor('black'))
+        brush.setStyle(Qt.SolidPattern)
+        rect = QtCore.QRect(0, 0, painter.device().width(), painter.device().height())
+        painter.fillRect(rect, brush)
+
+        # Get current state.
+        dial = self.parent()._dial
+        vmin, vmax = dial.minimum(), dial.maximum()
+        value = dial.value()
+
+        pc = (value - vmin) / (vmax - vmin)
+        n_steps_to_draw = int(pc * 5)
+
+        # Define our canvas
+        padding = 5
+        d_height = painter.device().height() - (padding * 2)
+        d_width = painter.device().width() - (padding * 2)
+
+        # Draw the bars
+        step_size = d_height / 5
+        bar_height = int(step_size * 0.6)
+        bar_spacer = int(step_size * 0.4 / 2)
+
+        brush.setColor(QtGui.QColor('red'))
+
+        for n in range(n_steps_to_draw):
+            rect = QtCore.QRect(
+                padding,
+                int(padding + d_height - ((n + 1) * step_size) + bar_spacer),
+                d_width,
+                bar_height
+            )
+            painter.fillRect(rect, brush)
+
+    def _trigger_refresh(self):
+        self.update()
+
+
+class PowerBar(QtWidgets.QWidget):
+    """
+    Custom Qt Widget to show a power bar and dial.
+    Demonstrating compound and custom-drawn widget.
+    """
+
+    def __init__(self, steps=5, *args, **kwargs):
+        super(PowerBar, self).__init__(*args, **kwargs)
+
+        layout = QtWidgets.QVBoxLayout()
+        self._bar = _Bar()
+        layout.addWidget(self._bar)
+
+        self._dial = QtWidgets.QDial()
+        layout.addWidget(self._dial)
+
+        self.setLayout(layout)
+        self._dial.valueChanged.connect(self._bar._trigger_refresh)
+
+
+if __name__ == '__main__':
+    app = QtWidgets.QApplication([])
+    volume = PowerBar()
+    volume.show()
+    app.exec_()

+ 150 - 0
power_bar_better.py

@@ -0,0 +1,150 @@
+from PyQt5 import QtWidgets, QtGui, QtCore
+from PyQt5.QtCore import Qt
+
+
+class _Bar(QtWidgets.QWidget):
+    clickedValue = QtCore.pyqtSignal(int)
+
+    def __init__(self, steps, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.setSizePolicy(
+            QtWidgets.QSizePolicy.MinimumExpanding,
+            QtWidgets.QSizePolicy.MinimumExpanding
+        )
+
+        if isinstance(steps, list):
+            # list of colors
+            self.n_steps = len(steps)
+            self.steps = steps
+        elif isinstance(steps, int):
+            self.n_steps = steps
+            self.steps = ['red'] * steps
+        else:
+            raise TypeError('step must be a list or int')
+
+        self._bar_solid_parent = 0.8
+        self._background_color = QtGui.QColor('black')
+        self._padding = 4.0
+
+    def sizeHint(self):
+        return QtCore.QSize(40, 120)
+
+    def paintEvent(self, e):
+        painter = QtGui.QPainter(self)
+        brush = QtGui.QBrush()
+        brush.setColor(self._background_color)
+        brush.setStyle(Qt.SolidPattern)
+        rect = QtCore.QRect(0, 0, painter.device().width(), painter.device().height())
+        painter.fillRect(rect, brush)
+
+        # Get current state.
+        dial = self.parent()._dial
+        vmin, vmax = dial.minimum(), dial.maximum()
+        value = dial.value()
+
+        pc = (value - vmin) / (vmax - vmin)
+        n_steps_to_draw = int(pc * self.n_steps)
+
+        # Define our canvas
+        padding = 5
+        d_height = painter.device().height() - (padding * 2)
+        d_width = painter.device().width() - (padding * 2)
+
+        # Draw the bars
+        step_size = d_height / self.n_steps
+        bar_height = int(step_size * self._bar_solid_parent)
+        bar_spacer = int(step_size * self._bar_solid_parent / 2)
+
+        for n in range(n_steps_to_draw):
+            brush.setColor(QtGui.QColor(self.steps[n]))
+            rect = QtCore.QRect(
+                padding,
+                int(padding + d_height - ((n + 1) * step_size) + bar_spacer),
+                d_width,
+                bar_height
+            )
+            painter.fillRect(rect, brush)
+
+    def _trigger_refresh(self):
+        self.update()
+
+    def _calculate_clicked_value(self, e):
+        parent = self.parent()
+        vmin, vmax = parent.minimum(), parent.maximum()
+        d_height = self.size().height() - (self._padding * 2)
+        step_size = d_height / self.n_steps
+        click_y = e.y() - self._padding - step_size / 2
+
+        pc = (d_height - click_y) / d_height
+        value = vmin + pc * (vmax - vmin)
+        self.clickedValue.emit(value)
+
+    def mouseMoveEvent(self, e: QtGui.QMouseEvent):
+        self._calculate_clicked_value(e)
+
+    def mouseReleaseEvent(self, e: QtGui.QMouseEvent):
+        self._calculate_clicked_value(e)
+
+
+class PowerBar(QtWidgets.QWidget):
+    """
+    Custom Qt Widget to show a power bar and dial.
+    Demonstrating compound and custom-drawn widget.
+
+    Left-clicking the button shows the color-chooser, while
+    right-clicking resets the color tho None (no color).
+    """
+
+    colorChanged = QtCore.pyqtSignal()
+
+    def __init__(self, steps=5, *args, **kwargs):
+        super(PowerBar, self).__init__(*args, **kwargs)
+
+        layout = QtWidgets.QVBoxLayout()
+        self._bar = _Bar(steps)
+        layout.addWidget(self._bar)
+
+        # Create the QDial widget and set up defaults.
+        self._dial = QtWidgets.QDial()
+        self._dial.setNotchesVisible(True)
+        self._dial.setWrapping(False)
+        self._dial.valueChanged.connect(self._bar._trigger_refresh)
+
+        self._bar.clickedValue.connect(self._dial.setValue)
+
+        layout.addWidget(self._dial)
+        self.setLayout(layout)
+
+    def __getattr__(self, name):
+        if name in self.__dict__:
+            return self[name]
+        return getattr(self._dial, name)
+
+    def setColor(self, color):
+        self._bar.steps = [color] * self._bar.n_steps
+        self._bar.update()
+
+    def setColors(self, colors):
+        self._bar.n_steps = len(colors)
+        self._bar.steps = colors
+        self._bar.update()
+
+    def setBarPadding(self, i):
+        self._bar._padding = int(i)
+        self._bar.update()
+
+    def setBarSolidPercent(self, f):
+        self._bar._bar_solid_percent = float(f)
+        self._bar.update()
+
+    def setBackgroundColor(self, color):
+        self._bar._background_color = QtGui.QColor(color)
+        self._bar.update()
+
+
+if __name__ == '__main__':
+    app = QtWidgets.QApplication([])
+    volume = PowerBar()
+    volume.show()
+    app.exec_()

+ 5 - 4
signal_data.py

@@ -1,6 +1,10 @@
 from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QWidget
 
 
+def my_custom_fn(n):
+    print("Button %d was clicked" % n)
+
+
 class MainWindow(QMainWindow):
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
@@ -9,7 +13,7 @@ class MainWindow(QMainWindow):
         layout = QVBoxLayout()
         for n in range(10):
             btn = QPushButton(str(n))
-            btn.pressed.connect(lambda val=n: self.my_custom_fn(val))
+            btn.pressed.connect(lambda val=n: my_custom_fn(val))
             layout.addWidget(btn)
 
         widget = QWidget()
@@ -17,9 +21,6 @@ class MainWindow(QMainWindow):
 
         self.setCentralWidget(widget)
 
-    def my_custom_fn(self, n):
-        print("Button %d was clicked" % n)
-
 
 if __name__ == '__main__':
     app = QApplication([])

+ 98 - 0
todo/mainwindow.ui

@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>444</width>
+    <height>402</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Todo</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QListView" name="todoView">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>10</y>
+      <width>421</width>
+      <height>192</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="deleteButton">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>220</y>
+      <width>113</width>
+      <height>32</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Delete</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="completeButton">
+    <property name="geometry">
+     <rect>
+      <x>320</x>
+      <y>220</y>
+      <width>113</width>
+      <height>32</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Complet</string>
+    </property>
+   </widget>
+   <widget class="QLineEdit" name="todoEdit">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>260</y>
+      <width>421</width>
+      <height>21</height>
+     </rect>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="addButton">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>300</y>
+      <width>431</width>
+      <height>32</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Add Todo</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>444</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <tabstops>
+  <tabstop>todoView</tabstop>
+  <tabstop>deleteButton</tabstop>
+  <tabstop>todoEdit</tabstop>
+  <tabstop>completeButton</tabstop>
+  <tabstop>addButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>

+ 60 - 0
todo/to_do.py

@@ -0,0 +1,60 @@
+import sys
+
+from PyQt5 import QtCore, uic, QtWidgets
+from PyQt5.QtCore import Qt
+
+qt_creator_file = "mainwindow.ui"
+Ui_MainWindow, QtBaseClass = uic.loadUiType(qt_creator_file)
+
+
+class TodoModel(QtCore.QAbstractListModel):
+    def __init__(self, *args, todos=None, **kwargs):
+        super(TodoModel, self).__init__(*args, **kwargs)
+        self.todos = todos or []
+
+    def data(self, index, role):
+        if role == Qt.DisplayRole:
+            status, text = self.todos[index.row()]
+            return text
+
+    def rowCount(self, index):
+        return len(self.todos)
+
+
+class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
+    def __init__(self):
+        QtWidgets.QMainWindow.__init__(self)
+        Ui_MainWindow.__init__(self)
+        self.setupUi(self)
+        self.module = TodoModel(todos=[(False, '我的第一个 Todo 项目')])
+        self.todoView.setModel(self.module)
+
+        self.addButton.pressed.connect(self.add)
+        self.deleteButton.pressed.connect(self.delete)
+
+    def add(self):
+        """
+        Add an item to our todo list, getting the text from the QLineEdit.todoEdit
+        and then clearing it.
+        :return:
+        """
+        text = self.todoEdit.text()
+        if text:
+            self.module.todos.append((False, text))
+            self.todoEdit.setText("")
+            self.module.layoutChanged.emit()
+
+    def delete(self):
+        indexes = self.todoView.selectedIndexes()
+        if indexes:
+            index = indexes[0]
+            del self.module.todos[index.row()]
+            self.todoView.clearSelection()
+            self.module.layoutChanged.emit()
+
+
+if __name__ == '__main__':
+    app = QtWidgets.QApplication(sys.argv)
+    window = MainWindow()
+    window.show()
+    app.exec_()

+ 6 - 6
widgets_gridlayout.py

@@ -1,12 +1,15 @@
 # Only needed for access to command line arguments
 import sys
 
-from PyQt5.QtCore import *
-from PyQt5.QtGui import QPixmap, QPalette, QColor
-from PyQt5.QtWidgets import *
+from PyQt5.QtGui import QPalette, QColor
+from PyQt5.QtWidgets import QMainWindow, QGridLayout, QWidget, QApplication
 
 
 # 自定义窗口,继承 QMainWindow
+def index_changed(s):
+    print(s)
+
+
 class MainWindow(QMainWindow):
     def __init__(self, *args, **kwargs):
         super(MainWindow, self).__init__(*args, **kwargs)
@@ -22,9 +25,6 @@ class MainWindow(QMainWindow):
         widget.setLayout(layout)
         self.setCentralWidget(widget)
 
-    def index_changed(self, s):
-        print(s)
-
 
 class Color(QWidget):
     def __init__(self, color, *args, **kwargs):